hdu 4578 Transformation(线段树)
线段树上的多操作。。。
题目大意:
树上 的初始值为0,然后有下列三种操作和求和。
1 x y c 在X-Y的之间全部加上C。
2 x y c 在X-Y的之间全部乘上C。
3 x y c 在X-Y之间的全部变成C。
4 x y c 输出在X-Y之间的所有数的C方的和。。。
思路:
因为存在两种不兼容的操作(如果直接放一起的话会出现顺序不同的影响,(3+2)*4 和 3*4+2 显然是不一样的)
所以每次合并操作的时候 就要把子树的操作推下去清除掉。
当然 如果这个区间的所有值都是一样的话。那么可以直接进行操作。
然后就是Query了。
因为要求出很多的平方 或者 立方和。
那么我们就去找所有区间的值是一样的区间。拿出来现乘方 再算有多少个。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 100005 const int mod = 10007; using namespace std; int add[maxn<<2]; int mul[maxn<<2]; int cov[maxn<<2]; int tre[maxn<<2]; int n,m; void pushdown(int num) { if(cov[num])//如果这个区间是值一样的 { tre[num<<1]=tre[num<<1|1]=tre[num]; cov[num<<1]=cov[num<<1|1]=1; add[num<<1]=add[num<<1|1]=0; mul[num<<1]=mul[num<<1|1]=1; cov[num]=0; return; } if(add[num]!=0)//不一样的话 要把ADD推下去 { if(cov[num<<1]) { tre[num<<1]+=add[num]; tre[num<<1]%=mod; } else { pushdown(num<<1); add[num<<1]+=add[num]; add[num<<1]%=mod; } if(cov[num<<1|1]) { tre[num<<1|1]+=add[num]; tre[num<<1|1]%=mod; } else { pushdown(num<<1|1); add[num<<1|1]+=add[num]; add[num<<1|1]%=mod; } add[num]=0; } if(mul[num]!=1) { if(cov[num<<1]) { tre[num<<1]*=mul[num]; tre[num<<1]%=mod; } else { mul[num<<1]*=mul[num]; mul[num<<1]%=mod; } if(cov[num<<1|1]) { tre[num<<1|1]*=mul[num]; tre[num<<1|1]%=mod; } else { mul[num<<1|1]*=mul[num]; mul[num<<1|1]%=mod; } mul[num]=1; } } void build(int num,int s,int e) { add[num]=0; mul[num]=1; cov[num]=0; tre[num]=0; if(s==e) { cov[num]=1; return; } int mid=(s+e)>>1; build(lson); build(rson); } void update(int num,int s,int e,int l,int r,int val,int op) { if(l<=s && r>=e) { if(op==3) { add[num]=0; mul[num]=1; cov[num]=1; tre[num]=val; } else { if(cov[num]) { if(op==1) { tre[num]+=val; tre[num]%=mod; } else { tre[num]*=val; tre[num]%=mod; } } else { pushdown(num); if(op==1) { add[num]+=val; add[num]%=mod; } else { mul[num]*=val; mul[num]%=mod; } } } return; } pushdown(num); int mid=(s+e)>>1; if(l<=mid)update(lson,l,r,val,op); if(r>mid)update(rson,l,r,val,op); } int Q_Q(int num,int s,int e,int c) { printf("```%d\n",num); int mid=(s+e)>>1; if(cov[num]==1) { int tmp=1; for(int aa=0;aa<c;aa++) { tmp*=tre[num]; tmp%=mod; } tmp*=(e-s+1); tmp%=mod; return tmp; } pushdown(num); Q_Q(lson,c); Q_Q(rson,c); } int query(int num,int s,int e,int l,int r,int c) { int mid=(s+e)>>1; if(l==s && r==e) { if(cov[num]) { int tmp=1; while(c--) { tmp*=tre[num]; tmp%=mod; } tmp*=(e-s+1); tmp%=mod; return tmp; } } pushdown(num); if(r<=mid)return query(lson,l,r,c); else if(l>mid)return query(rson,l,r,c); else return (query(lson,l,mid,c) + query(rson,mid+1,r,c))%mod; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0 && m==0)break; int op,lef,rig,c; build(1,1,n); while(m--) { scanf("%d%d%d%d",&op,&lef,&rig,&c); if(op!=4)update(1,1,n,lef,rig,c,op); else printf("%d\n",query(1,1,n,lef,rig,c)%mod); } } return 0; }