lightOJ 1135 lazy 操作

来源:互联网 发布:windows操作系统平板 编辑:程序博客网 时间:2024/05/16 13:42
有n个数,刚开始都为0 http://www.cnblogs.com/wuyiqi/archive/2012/05/27/2520642.html
add i , j 给i,j区间内的数都加1
Q i j 询问i、j间能被三整除的数的个数http://lightoj.com/volume_showproblem.php?problem=1135
线段树记录三个域
对三取余为0的数的个数
。。。。。1.。。。。。
。。。。。2.。。。。。
可以保存在一个数组里面
考虑到每次给一个区间加1的时候,区间内对3取余为1的数的个数变成了对三取余为2,2的变成了0,0的变成了1

所以每次更新到区间或者把信息(懒惰标记)往下传的时候只需要把相应的域做一下调整即可

做题过程:(在程序里面有写)

       我发觉数组真的是和我过不去额。又开小了。10^5我以为5个1就行了呢。。。

       然后就是我常犯的毛病:不看题(人家是从0-n-1),还有就是初始化(lazy没有初始化)。

       这些都是后来的事情了。刚开始我图方便,将build直接写成memset了。然后一看结果输出的都是0,我就煞那间醒悟了,但是把lazy给漏掉了。。。

       还有一点是中间需要一个ans数组作为中间变量,不然的话,原来的值就被覆盖了。

       最后优化的一点是将那个1转成2等等的东西写成一个函数。

//started at 22:18//submit at 22:47 RE//change the size of shuzu ,submit at 22:49 WA//change the start point and end point , submit at 22:51 WA//change lazy[](initualize) ,submit ant 22 : 55, AC#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define lson l, m , rt << 1#define rson m + 1, r, rt << 1 | 1#define ls rt << 1#define rs rt << 1 | 1#define maxn 111111//RE了一次#define havem int m = (l + r) >> 1int hehe[3][maxn << 2],ans[3],lazy[maxn << 2];void push_up(int rt){    for(int i = 0; i < 3; i ++){        hehe[i][rt] = hehe[i][ls] + hehe[i][rs];    }}void build(int l,int r,int rt){    lazy[rt] = 0;//这里wa了一次    if(l == r){        hehe[0][rt] = 1;        hehe[1][rt] = hehe[2][rt] = 0;        return ;    }havem;    build(lson); build(rson);    push_up(rt);}int t,n,Q,op,a,b;void make(int add, int rt){//这里优化了一下    for(int i = 0; i < 3; i ++){        ans[(i + add) % 3] = hehe[i][rt];    }    for(int i = 0; i < 3; i ++){        hehe[i][rt] = ans[i];    }}void push_dn(int rt){    if(lazy[rt]){        int tmp = lazy[rt];        lazy[ls] += tmp;        lazy[rs] += tmp;        make(tmp,ls);        make(tmp,rs);        lazy[rt] = 0;    }}void update(int L, int R,int l,int r, int rt){    if(L <= l && r <= R){        lazy[rt] += 1;    //question : how do you increase the number        make(1,rt);        return;    }havem;    push_dn(rt);    if(L <= m) update(L,R,lson);    if(R > m) update(L,R,rson);    push_up(rt);}int query(int L,int R,int l,int r,int rt){    if(L <= l && r <= R)    return hehe[0][rt];    int ret = 0;    havem;  push_dn(rt);    if(L <= m) ret = query(L,R,lson);    if(R > m) ret += query(L,R,rson);    return ret;}int main(){    scanf("%d",&t);    for(int ca = 1; ca <= t; ca ++){        scanf("%d%d",&n,&Q);        build(0,n - 1,1);//从0-n-1,wa了一次        memset(ans,0,sizeof(ans));        printf("Case %d:\n",ca);        for(int i = 1; i <= Q; i ++){            scanf("%d",&op);            scanf("%d%d",&a,&b);            if(op == 0){                update(a,b,0,n - 1,1);            }else                printf("%d\n",query(a,b,0,n - 1,1));        }    }    return 0;}