I am trying to solve the flipping coin problem and unable to understand the lazy propagation method clearly. I searched on internet and found some codes.
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define MAX 300000
#define loop0(i,j) for(int i=0;i<j;i++)
#define loop1(i,j) for(int i=1;i<j;i++)
using namespace std;
bool flag[MAX];
int value[MAX];
/*void initialize(int node, int b, int e)
{
if (b == e)
{
flag[node] = false;
value[node] = 0;
}
else
{
initialize(2 * node, b, (b + e) / 2);
initialize(2 * node + 1, (b + e) / 2 + 1, e);
value[node] = 0;
flag[node] = false;
}
}*/
int update(int node, int b, int e, int i, int j)
{
int p1, p2;
if (i > e || j < b)
return 0;
if (b >= i && e <= j)
{
if(b==e)
{
if(flag[node] == true)
return 1;
else
return 0;
}
else if(flag[node] == true)
{
flag[node] = false;
flag[2*node] = !flag[2*node];
flag[2*node+1] = !flag[2*node+1];
p1 = update(2 * node, b, (b + e) / 2, i, j);
p2 = update(2 * node + 1, (b + e) / 2 + 1, e, i, j);
return value[node] = p1 + p2;
}
else
return value[node];
}
else
{
if(flag[node]==true)
{
flag[node]=false;
flag[2*node]=!flag[2*node];
flag[2*node+1]=!flag[2*node+1];
}
p1 = update(2 * node, b, (b + e) / 2, i, j);
p2 = update(2 * node + 1, (b + e) / 2 + 1, e, i, j);
return value[node] = p1 + p2;
}
}
int query(int node, int b, int e, int i, int j)
{
int p1, p2;
if (i > e || j < b)
return 0;
if (b >= i && e <= j)
{
flag[node] = !flag[node];
return value[node] = e - b + 1 - value[node];
}
else
{
if(flag[node]==true)
{
flag[node]=false;
flag[2*node]=!flag[2*node];
flag[2*node+1]=!flag[2*node+1];
}
p1 = query(2 * node, b, (b + e) / 2, i, j);
p2 = query(2 * node + 1, (b + e) / 2 + 1, e, i, j);
if(p1==-1)
p1=0;
if(p2==-1)
p2=0;
return (value[node] = p1 + p2);
}
}
int main()
{
int k, t, tests, m, n;
int f, a, b, z;
// cin >> tests >> m;
scanf("%d %d",&tests,&m);
// initialize(1, 0, tests-1);
loop0(i, m)
{
scanf("%d %d %d",&f,&a,&b);
// cin >> f >> a >> b;
if(f==0)
value[1] = query(1,0,tests-1,a,b);
else
printf("%d\n",update(1,0,tests-1,a,b));
// cout << update(1,0,tests-1,a,b) <<"\n";
}
return 0;
}
I don't know whether this is correct or not because its still giving TLE on Codechef. Please explain lazy propagation in detail or tell whether this code is correct or not. I will try to understand it according to the code.
hey i'm getting WA in flipping coins at codechef can u point out where the mistake might be.i've used lazy propagation and the flags are used to denote that if the coins in the range have to be flipped or not.
here is my code
the problem is codechef.com/problems/FLIPCOIN1
thanks got ac
i have another problem with lazy propagation method :
suppose we have 4 kind of updates operation consequently, and then a query for a range result . so 4 update should be done on some ranges one by one , but i think having 4 updates consequently on big intervals don't allow to updates done one by one on small intervals and this cause a problem.
let's see an example on FlipConis Problem (codechef.com/problems/FLIPCOIN) :
6 5
0 0 6
0 0 3
0 2 5
0 1 6
1 1 6
so what's the order of updates ? when updates done on small intervals ??
i'm so confused about how several updates done one by one.
sorry for my poor english
thanks
another issue !
i think this problem (FlipCoin) maybe can be solved by this kind of lazy propagation , but imagine we have 3 TYPE of update operations (like problem: uva.onlinejudge.org/external/114/11402.html) , so what should we do on this ?
When updating you only update until you reach a node where you are updating the entire range, then you flag it for update.
When querying, of you reach a node that is flagged for update, then you perform the update on it and push the flag for update to it's children.
0 0 6
Update value in 0,6 and turn flag for update on.
0 0 3
Push update from 0,6 to 0,3 and 4,6 and update their values.
Update value in 0,3 and turn flag for update off.
0 2 5
Update value in 2,3 and turn flag for update on.
Push update from 4,6 to 4,5 and 6,6 and update their values.
Update value in 4,5 and turn flag for update off.
0 1 6
Update value in 1,1 and turn flag for update on.
Update value in 2,3 and turn flag for update off.
Update value in 4,6 and turn flag for update on.
1 1 6
Return value from 1,1
Return value from 2,3
Return value from 4,6
If you have read the rest of the topic you know that whenever I have an update flag set on a node it's value is correct but every node below it needs to be updated.
@leppy :
can you please have a look at this code implementing the idea you suggested earlier in this post. Its working fine for me but giving WA on LITE problem testcases.
resolved, nice thread on lazy prop.
thanks!
was buggy: removed.
Suggested Topics
Topic | Category | Replies | Views | Activity |
---|---|---|---|---|
Hosting a competition on SPOJ | Off-topic | 1 | 129 | Apr 9 |