hdu 4578 區間線段樹
阿新 • • 發佈:2019-02-05
很裸的線段樹,由於一個乘號寫成加號調了一下午,總算搞定了。
ACcode:
#include<cstdio> #include<cstring> typedef long long LL; const int NS=100010; const int MOD=10007; #define lc (rt<<1) #define rc (rt<<1|1) #define now seg[rt] struct node{ int l,r; int add,mul; int s[3]; }seg[NS<<2]; int n,m; void build(int rt,int l,int r) { for (int i=0;i<3;i++) now.s[i]=0; now.l=l,now.r=r; now.add=0,now.mul=1; if (l==r) return ; int mid=(l+r)>>1; build(lc,l,mid); build(rc,mid+1,r); } void Pushdown(int rt) { int len1=seg[lc].r-seg[lc].l+1; int len2=seg[rc].r-seg[rc].l+1; int v=now.mul,c; if (v!=1) { node t1=seg[lc],t2=seg[rc]; c=v; t1.mul*=v,t1.mul%=MOD; t1.add*=v,t1.add%=MOD; for (int i=0;i<3;i++) t1.s[i]*=c,c*=v,c%=MOD; c=v; t2.mul*=v,t2.mul%=MOD; t2.add*=v,t2.add%=MOD; for (int i=0;i<3;i++) t2.s[i]*=c,c*=v,c%=MOD; for (int i=0;i<3;i++) t1.s[i]%=MOD,t2.s[i]%=MOD; seg[lc]=t1,seg[rc]=t2; now.mul=1; } v=now.add; if (v!=0) { node t1=seg[lc],t2=seg[rc]; c=v; t1.add+=v,t1.add%=MOD; t1.s[0]+=len1*c; c*=v,c%=MOD; t1.s[1]=seg[lc].s[1]+len1*c+2*seg[lc].s[0]*v; c*=v,c%=MOD; t1.s[2]=seg[lc].s[2]+len1*c+3*seg[lc].s[1]*v+3*seg[lc].s[0]*(v*v%MOD); c=v; t2.add+=v,t2.add%=MOD; t2.s[0]+=len2*c; c*=v,c%=MOD; t2.s[1]=seg[rc].s[1]+len2*c+2*seg[rc].s[0]*v; c*=v,c%=MOD; t2.s[2]=seg[rc].s[2]+len2*c+3*seg[rc].s[1]*v+3*seg[rc].s[0]*(v*v%MOD); for (int i=0;i<3;i++) t1.s[i]%=MOD,t2.s[i]%=MOD; seg[lc]=t1,seg[rc]=t2; now.add=0; } } void Pushup(int rt) { for (int i=0;i<3;i++) now.s[i]=(seg[lc].s[i]+seg[rc].s[i])%MOD; } void update(int rt,int L,int R,int v,int op) { if (L<=now.l&&now.r<=R) { node tmp=now; if(op==1) { tmp.add+=v,tmp.add%=MOD; int c=v,len=now.r-now.l+1; tmp.s[0]+=len*c; c*=v,c%=MOD; tmp.s[1]=now.s[1]+len*c+2*now.s[0]*v; c*=v,c%=MOD; tmp.s[2]=now.s[2]+len*c+3*now.s[1]*v+3*now.s[0]*(v*v%MOD); } else if (op==2) { tmp.mul*=v,tmp.mul%=MOD; tmp.add*=v,tmp.add%=MOD; for (int c=v,i=0;i<3;i++) tmp.s[i]*=c,c*=v,c%=MOD; } else { tmp.mul=0; tmp.add=v; int len=now.r-now.l+1; for (int c=v,i=0;i<3;i++) tmp.s[i]=len*c,c*=v,c%=MOD; } for (int i=0;i<3;i++) tmp.s[i]%=MOD; now=tmp; return ; } Pushdown(rt); int mid=(now.l+now.r)>>1; if (L<=mid) update(lc,L,R,v,op); if (R>mid) update(rc,L,R,v,op); Pushup(rt); } int query(int rt,int L,int R,int p) { if (L<=now.l&&now.r<=R) return now.s[p]; Pushdown(rt); int ans=0; int mid=(now.l+now.r)>>1; if (L<=mid) ans+=query(lc,L,R,p); if (R>mid) ans+=query(rc,L,R,p); ans%=MOD; return ans; } int main() { while (~scanf("%d%d",&n,&m)&&(n+m)) { build(1,1,n); int op,x,y,p; for (;m;m--) { scanf("%d%d%d%d",&op,&x,&y,&p); if (op!=4){ update(1,x,y,p,op); } else { int ans=query(1,x,y,p-1); printf("%d\n",ans); } } } return 0; }