31 / 31
Aug 2012

I replace the cout and cin for scanf and printf and I get accepted!!!!!!!!! smiley smiley smiley smiley smiley

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.

Ignore the code and focus on the posts that I have already made in this topic. Those posts are the main reason that I created this topic.

Do you understand a segment tree correctly first? It's a prerequisite for understanding lazy propagation.

yeah I understood the segment tree, but without lazy propagation its useless. Ok will try to do it again. Doing it from past 10 days

Are you operating using my method where the value in a node with a flag is correct? If so, then this is incorrect:

        if(flag[node]==true)
        {
            flag[node]=false;
            flag[2*node]=!flag[2*node];
            flag[2*node+1]=!flag[2*node+1];
        }
8 days later

Leppy please help us with some code for update range [i,j] and query sum[i,j]. Except your explanation can't find anything on the internet.Even you explained very clear still fail to implement. It would be really useful not only for me. Thanks.

I prefer not to write code. If you are having a specific problem please feel free to post your misunderstanding and I can attempt to help you.

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

Please use code tags when posting code. Please post a link to the problem.

Think carefully about why you are performing each step. You will quickly find your mistake if you think about what you are doing. This is a very important skill to learn.

10 days later

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 smile
thanks

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.

As for the other problem that you posted, it's nt that difficult. You just need to get more creative with your update flag.

26 days later

@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.

if(p==0) update(0, 1, lim, q, r);  
else if(p==1) cout<<get(0,1,lim,q,r)<<endl;

Use S instead of lim.

Suggested Topics

Topic Category Replies Views Activity
Off-topic 1 129 Apr 9

Want to read more? Browse other topics in Off-topic or view latest topics.