Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 3830 Accepted Submission(s): 940
#include<bits/stdc++.h> using namespace std; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R typedef long long INT; const int maxn = 120000; const int mod = 10007; struct SegTree{ int add,multi,setv; int sum1,sum2,sum3; }segs[maxn*4]; void PushUp(int rt,int L,int R){ segs[rt].sum1 = (segs[rt*2].sum1 + segs[rt*2+1].sum1)% mod; segs[rt].sum2 = (segs[rt*2].sum2 + segs[rt*2+1].sum2)% mod; segs[rt].sum3 = (segs[rt*2].sum3 + segs[rt*2+1].sum3)% mod; } void buildtree(int rt,int L,int R){ segs[rt].multi = 1; segs[rt].add = segs[rt].setv = 0; segs[rt].sum1 = segs[rt].sum2 = segs[rt].sum3 = 0; if(L == R){ return ; } buildtree(lson); buildtree(rson); } void PushDown(int rt,int L,int R){ if(segs[rt].setv){ //考虑下放赋值标记 segs[rt*2].setv = segs[rt*2+1].setv = segs[rt].setv; segs[rt*2].add = segs[rt*2+1].add = 0; segs[rt*2].multi = segs[rt*2+1].multi = 1; segs[rt*2].sum1 = (mid-L+1)*segs[rt].setv % mod; segs[rt*2].sum2 = (mid-L+1)*segs[rt].setv %mod *segs[rt].setv % mod; segs[rt*2].sum3 = (mid-L+1)*segs[rt].setv %mod *segs[rt].setv % mod *segs[rt].setv % mod; segs[rt*2+1].sum1 = (R-mid)*segs[rt].setv % mod; segs[rt*2+1].sum2 = (R-mid)*segs[rt].setv % mod *segs[rt].setv % mod; segs[rt*2+1].sum3 = (R-mid)*segs[rt].setv % mod *segs[rt].setv % mod *segs[rt].setv % mod; segs[rt].setv = 0; } if(segs[rt].multi != 1 || segs[rt].add){//如果有加和标记或者乘积标记 segs[rt*2].add = (segs[rt].multi * segs[rt*2].add %mod + segs[rt].add) % mod; segs[rt*2].multi = segs[rt].multi * segs[rt*2].multi % mod; int sum1, sum2 ,sum3; //一次方和 sum1 = (segs[rt*2].sum1*segs[rt].multi %mod + (mid-L+1)*segs[rt].add %mod) % mod; //平方和 sum2 = (segs[rt*2].sum2*segs[rt].multi %mod *segs[rt].multi %mod + 2*segs[rt].add * segs[rt].multi %mod *segs[rt*2].sum1 %mod + (mid-L+1)*segs[rt].add %mod *segs[rt].add %mod ) % mod; //三次方和 sum3 = segs[rt*2].sum3*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt].multi %mod; sum3 = (sum3 + 3*segs[rt].add*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt*2].sum2 %mod) % mod; sum3 = (sum3 + 3*segs[rt].add*segs[rt].add %mod *segs[rt].multi %mod *segs[rt*2].sum1 %mod ) % mod; sum3 = (sum3 + (mid-L+1)*segs[rt].add %mod *segs[rt].add %mod *segs[rt].add %mod ) % mod; segs[rt*2].sum1 = sum1; segs[rt*2].sum2 = sum2; segs[rt*2].sum3 = sum3; //同理,更新右儿子 segs[rt*2+1].add = (segs[rt*2+1].add*segs[rt].multi %mod + segs[rt].add) % mod; segs[rt*2+1].multi = segs[rt*2+1].multi * segs[rt].multi % mod; sum1 = (segs[rt*2+1].sum1*segs[rt].multi %mod + (R-mid)*segs[rt].add %mod) % mod; sum2 = (segs[rt*2+1].sum2*segs[rt].multi %mod *segs[rt].multi %mod + 2*segs[rt].add*segs[rt].multi %mod *segs[rt*2+1].sum1 %mod + (R-mid)*segs[rt].add %mod *segs[rt].add %mod) % mod; sum3 = segs[rt*2+1].sum3*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt].multi %mod; sum3 = (sum3 + 3*segs[rt].add*segs[rt].multi %mod *segs[rt].multi %mod *segs[rt*2+1].sum2 %mod) % mod; sum3 = (sum3 + 3*segs[rt].add*segs[rt].add %mod *segs[rt].multi %mod *segs[rt*2+1].sum1 %mod ) % mod; sum3 = (sum3 + (R-mid)*segs[rt].add %mod *segs[rt].add %mod *segs[rt].add %mod ) % mod; segs[rt*2+1].sum1 = sum1; segs[rt*2+1].sum2 = sum2; segs[rt*2+1].sum3 = sum3; segs[rt].add = 0; segs[rt].multi = 1; } } void Update(int rt,int L,int R,int l_ran,int r_ran,int c,int typ){ if(l_ran <= L&&R <= r_ran){ if(typ == 1){ //加和 segs[rt].add = (segs[rt].add + c)%mod; segs[rt].sum3 = (segs[rt].sum3 + (R-L+1)*c %mod *c %mod *c %mod + 3*c %mod *segs[rt].sum2 %mod + 3*c %mod *c %mod *segs[rt].sum1 %mod ) % mod; segs[rt].sum2 = (segs[rt].sum2 + (R-L+1)*c %mod *c %mod + 2*segs[rt].sum1 %mod *c %mod ) % mod; segs[rt].sum1 = ((R-L+1)*c %mod + segs[rt].sum1) % mod; }else if(typ == 2){ //乘积 //乘积对当前节点的和跟乘都有影响 segs[rt].add = segs[rt].add * c % mod; segs[rt].multi = segs[rt].multi * c % mod; segs[rt].sum1 = segs[rt].sum1 * c % mod; segs[rt].sum2 = segs[rt].sum2 * c %mod *c %mod; segs[rt].sum3 = segs[rt].sum3 *c %mod *c %mod *c % mod; }else{ //赋值 segs[rt].setv = c; segs[rt].multi = 1; segs[rt].add = 0; segs[rt].sum1 = c*(R-L+1) % mod; segs[rt].sum2 = c*(R-L+1) % mod*c % mod; segs[rt].sum3 = c*(R-L+1) % mod*c % mod *c %mod ; } return ; } PushDown(rt,L,R); if(l_ran <= mid) Update(lson,l_ran,r_ran,c,typ); if(r_ran > mid) Update(rson,l_ran,r_ran,c,typ); PushUp(rt,L,R); } int query(int rt,int L,int R,int l_ran,int r_ran,int pw){ if(l_ran <= L&&R <= r_ran){ if(pw == 1){ return segs[rt].sum1; }else if(pw == 2){ return segs[rt].sum2; }else{ return segs[rt].sum3; } } PushDown(rt,L,R); int ret = 0; if(l_ran <= mid){ ret = (ret + query(lson,l_ran,r_ran,pw)) % mod; } if(r_ran > mid){ ret = (ret + query(rson,l_ran,r_ran,pw)) % mod; } return ret; } int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){ int c,u,v,w; buildtree(1,1,n); for(int i = 1; i <= m; i++){ scanf("%d%d%d%d",&c,&u,&v,&w); if(c == 4){ int res = query(1,1,n,u,v,w); printf("%d\n",res); }else { Update(1,1,n,u,v,w,c); } } } return 0; }
HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】
原文:http://www.cnblogs.com/chengsheng/p/4975396.html