HDOJ 4578 线段树

来源:互联网 发布:拼接屏调试软件 编辑:程序博客网 时间:2024/05/01 02:20

关键问题是要同时维护每个节点的三个值,sum【1】一次方,sum【2】二次方,sum【3】三次方,还有个update()维护每次的sum值的改变。

然后有个lazy【】标记,既然有lazy标记,就要有pushdown的维护。三种操作,+c,*c,=c,显然=c优先级最高,然后是*c,最后是+c,维护每个节点扣留的操作,需要按照这种顺序。

可是写出来wa了4遍。

对线段树的理解还是不够透彻。

留个链接吧,http://blog.csdn.net/kk303/article/details/9900919,以后再看。

有误的代码。。。


#include <iostream>#include <fstream>#include <cstring>using namespace std;#define N 100005#define T 10007int sum[N*4][4],ord[N*4][4];bool lazy[N*4];int n,m;void update(int op,int len,int c,int now){    len=len%T;    if (op==3){        sum[now][1]=len*c%T;        sum[now][2]=sum[now][1]*c%T;        sum[now][3]=sum[now][2]*c%T;    }    else    if (op==2){        sum[now][1]=sum[now][1]*c%T;        sum[now][2]=sum[now][2]*c%T*c%T;        sum[now][3]=(sum[now][3]*((c*c)%T))%T*c%T;    }    else {        sum[now][3]=sum[now][3]+3*sum[now][2]*c%T+3*(sum[now][1]*c)%T*c%T+(c*c)%T*(c*len)%T%T;        sum[now][2]=sum[now][2]+2*sum[now][1]*c%T+(c*c)%T*len%T;        sum[now][1]=sum[now][1]+c*len%T;    }}void PushDown(int len,int now){    if (!lazy[now]) return;    lazy[now]=false;    lazy[now<<1]= lazy[now<<1|1] =true;    if (ord[now][3]){        update(3,len-(len>>1),ord[now][3],now<<1);        update(3,len>>1,ord[now][3],now<<1|1);        for (int i=1;i<4;i++)            ord[now<<1][i] = ord[now<<1|1][i] = ord[now][i];    }    else {        ord[now<<1][2]=ord[now<<1][2]*ord[now][2]%T;        ord[now<<1][1]=(ord[now<<1][1]*ord[now][2]%T+ord[now][1])%T;        ord[now<<1|1][2]=ord[now<<1|1][2]*ord[now][2]%T;        ord[now<<1|1][1]=(ord[now<<1|1][1]*ord[now][2]%T+ord[now][1])%T;    }    update(2,len-(len>>1),ord[now][2],now<<1);    update(1,len-(len>>1),ord[now][1],now<<1);    update(2,len>>1,ord[now][2],now<<1|1);    update(1,len>>1,ord[now][1],now<<1|1);    ord[now][3] = ord[now][1] = 0;    ord[now][2] = 1;    return ;}void Insert(int op,int L,int R,int c,int l,int r,int now){    if (L<=l && r<=R){        update(op,r-l+1,c,now);        lazy[now]=true;        if (op==3){            ord[now][3]=c,ord[now][2]=1,ord[now][1]=0;        }        else if (op==2){            ord[now][1]=ord[now][1]*c%T;            ord[now][2]=ord[now][2]*c%T;        }        else {            ord[now][1]=(ord[now][1]+c)%T;        }        return ;    }    PushDown(r-l+1,now);    int mid=(r+l)>>1;    if (L<=mid) Insert(op,L,R,c,l,mid,now<<1);    if (R>mid) Insert(op,L,R,c,mid+1,r,now<<1|1);    for (int i=1;i<4;i++)        sum[now][i]=(sum[now<<1][i]+sum[now<<1|1][i])%T;    return ;}int Search(int L,int R,int c,int l,int r,int now){    if (L<=l && R>=r){        return sum[now][c];    }    PushDown(r-l+1,now);    int mid=(l+r)>>1;    int ans=0;    if (L<=mid) ans+=Search(L,R,c,l,mid,now<<1);    if (mid<R) ans+=Search(L,R,c,mid+1,r,now<<1|1);    return ans%T;}int main(){    freopen("1.in","r",stdin);    //freopen("1.out","w",stdout);    scanf("%d%d",&n,&m);    while (!(n==0 && m==0)){        memset(sum,0,sizeof(sum));        memset(ord,0,sizeof(ord));        for (int i=1;i<=4*N;i++) ord[i][2]=1;        memset(lazy,false,sizeof(lazy));        for (int i=0;i<m;i++){            int op,l,r,c;            scanf("%d%d%d%d",&op,&l,&r,&c);            c=c%T;            if (op<=3) Insert(op,l,r,c,1,n,1);            else printf("%d\n",Search(l,r,c,1,n,1));        }        scanf("%d%d",&n,&m);    }    return 0;}


原创粉丝点击