题意:
有n个数一开始全为0,现在有m个操作.
1 a b c :将[a,b]区间的数全部加c
2 a b c :将[a,b]区间的数全部乘c
3 a b c :将[a,b]区间的数全部set成c
4 a b p :询问[a,b]区间的数的p次方的和
题解:
2,3操作都方便操作,1要推一下公式。
(a + c)2 = a2 + c2 + 2ac , 即sum2[rt] = sum2[rt] + (r - l + 1) * c * c + 2 * sum1[rt] * c;
(a + c)3 = a3 + c3 + 3a(a2 + ac) , 即sum3[rt] = sum3[rt] + (r - l + 1) * c * c * c + 3 * c * (sum2[rt] + sum1[rt] * c);
然后要注意的坑点:
mul的时候add也要成上c,set的时候mul要变为1,add变为0。
然后pushdown的时候先更新set,然后更新mul,然后add。
1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<<1|1 4 #define mst(a,b) memset(a,b,sizeof(a)) 5 #define F(i,a,b) for(int i=a;i<=b;++i) 6 using namespace std; 7 8 const int N=1e5+7,P=10007; 9 10 int add[N*4],mul[N*4],chang[N*4],sum[N*4][4]; 11 12 int n,m; 13 14 void del(int a,int num,int d,int rt) 15 { 16 if(a==1) 17 { 18 add[rt]=(add[rt]+d)%P; 19 sum[rt][3]=(sum[rt][3]+d*d%P*d%P*num%P+3*d*sum[rt][2]%P+3*d*d%P*sum[rt][1]%P)%P; 20 sum[rt][2]=(sum[rt][2]+d*d%P*num%P+2*d*sum[rt][1]%P)%P; 21 sum[rt][1]=(sum[rt][1]+num*d)%P; 22 } 23 else if(a==2) 24 { 25 add[rt]=add[rt]*d%P; 26 mul[rt]=(mul[rt]*d)%P; 27 sum[rt][1]=sum[rt][1]*d%P; 28 sum[rt][2]=sum[rt][2]*d%P*d%P; 29 sum[rt][3]=sum[rt][3]*d%P*d%P*d%P; 30 } 31 else 32 { 33 add[rt]=0; 34 mul[rt]=1; 35 chang[rt]=d%P; 36 sum[rt][1]=d*num%P; 37 sum[rt][2]=d*d%P*num%P; 38 sum[rt][3]=d*d%P*d%P*num%P; 39 } 40 } 41 42 void pd(int rt,int l,int r) 43 { 44 int m=l+r>>1; 45 if(chang[rt]) 46 { 47 del(3,m-l+1,chang[rt],rt<<1); 48 del(3,r-m,chang[rt],rt<<1|1); 49 chang[rt]=0; 50 } 51 if(mul[rt]!=1) 52 { 53 del(2,m-l+1,mul[rt],rt<<1); 54 del(2,r-m,mul[rt],rt<<1|1); 55 mul[rt]=1; 56 } 57 if(add[rt]) 58 { 59 del(1,m-l+1,add[rt],rt<<1); 60 del(1,r-m,add[rt],rt<<1|1); 61 add[rt]=0; 62 } 63 } 64 65 void up(int rt) 66 { 67 F(i,1,3)sum[rt][i]=(sum[rt<<1][i]+sum[rt<<1|1][i])%P; 68 } 69 70 void update(int a,int b,int c,int d,int l=1,int r=n,int rt=1) 71 { 72 if(b<=l&&r<=c) 73 { 74 del(a,r-l+1,d,rt); 75 return; 76 } 77 pd(rt,l,r); 78 int m=l+r>>1; 79 if(b<=m)update(a,b,c,d,ls); 80 if(c>m)update(a,b,c,d,rs); 81 up(rt); 82 } 83 84 int ask(int L,int R,int p,int l=1,int r=n,int rt=1) 85 { 86 if(L<=l&&r<=R)return sum[rt][p]; 87 pd(rt,l,r); 88 int m=l+r>>1,ans=0; 89 if(L<=m)ans=(ans+ask(L,R,p,ls))%P; 90 if(R>m)ans=(ans+ask(L,R,p,rs))%P; 91 up(rt); 92 return ans; 93 } 94 95 int main() 96 { 97 while(scanf("%d%d",&n,&m),n+m) 98 { 99 mst(add,0),mst(mul,0),mst(chang,0),mst(sum,0); 100 int a,b,c,d; 101 F(i,1,m) 102 { 103 scanf("%d%d%d%d",&a,&b,&c,&d); 104 if(a!=4)update(a,b,c,d); 105 else printf("%d ",ask(b,c,d)); 106 } 107 } 108 return 0; 109 }