题目大意:
题意:有一个序列,有四种操作:
1:区间[l,r]内的数全部加c。
2:区间[l,r]内的数全部乘c。
3:区间[l,r]内的数全部初始为c。
4:询问区间[l,r]内所有数的P次方之和。
这里p可以等于1,2,3三种情况,所以我们需要建立3个数组,当然这里其实只用一个sum[4*N][3]的2维数组其实更好
to[],add[],mul[]为三个懒惰标记to[]先于另外两个,每次做完to[],另外两个标记就要将其初始化
对于mul[]来说,每次执行,add[cur]*=mul[cur]也要随之增加
因为这道题目数过大,需要求mod 10007的值
因为这个我把代码从上午看到了下午简直要疯了
int最大值2147483647
你必须每执行一步操作都需要mod一次,*2后,10007*2*10007 int还不至于爆掉,但也差不多
但是若*3之后那肯定要是再碰到一个超大数,那就GG了
所以每次乘法算完都mod一次吧,每次做mod带上括号是一个好习惯~~
1 //这鬼题目里面最好每执行一次乘法就mod一次,不然可能int要爆掉导致报错,尤其是我在fun_add()中改错改了一天才发现是这个原因 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define N 100005 6 #define mod 10007 7 int sum[4*N][3],add[4*N],to[4*N],mul[4*N]; 8 void update(int cur) 9 { 10 sum[cur][0]=(sum[cur<<1][0]+sum[cur<<1|1][0])%mod; 11 sum[cur][1]=(sum[cur<<1][1]+sum[cur<<1|1][1])%mod; 12 sum[cur][2]=(sum[cur<<1][2]+sum[cur<<1|1][2])%mod; 13 } 14 void build(int cur,int x,int y) 15 { 16 int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1; 17 add[cur]=0,to[cur]=0,mul[cur]=1; 18 if(x==y){ 19 sum[cur][0]=sum[cur][1]=sum[cur][2]=0; 20 return; 21 } 22 build(ls,x,mid); 23 build(rs,mid+1,y); 24 update(cur); 25 } 26 void fun_mul(int cur,int x,int y,int val) 27 { 28 mul[cur]*=val; 29 mul[cur]%=mod; 30 add[cur]*=val; 31 add[cur]%=mod; 32 33 int t1=val*val%mod; 34 int t2=t1*val%mod; 35 sum[cur][0]=sum[cur][0]*val; 36 sum[cur][0]%=mod; 37 38 sum[cur][1]=sum[cur][1]*t1; 39 sum[cur][1]%=mod; 40 41 sum[cur][2]=sum[cur][2]*t2; 42 sum[cur][2]%=mod; 43 } 44 void fun_add(int cur,int x,int y,int val) 45 { 46 add[cur]+=val; 47 add[cur]%=mod; 48 int t1=sum[cur][0]; 49 int t2=sum[cur][1]; 50 int tmp1=val*val%mod; 51 int tmp2=val*tmp1%mod; 52 sum[cur][0]+=(y-x+1)*val; 53 sum[cur][0]%=mod; 54 55 sum[cur][1]+=(y-x+1)*tmp1%mod+((2*val)%mod)*t1%mod; 56 sum[cur][1]%=mod; 57 58 sum[cur][2]+=((3*val)%mod)*t2%mod+3*tmp1*t1%mod+(y-x+1)*tmp2%mod; 59 sum[cur][2]%=mod; 60 } 61 void fun_to(int cur,int x,int y,int val) 62 { 63 mul[cur]=1,add[cur]=0,to[cur]=val%mod; 64 int t1=val*val%mod; 65 int t2=t1*val%mod; 66 sum[cur][0]=(y-x+1)*val%mod; 67 sum[cur][1]=(y-x+1)*t1%mod; 68 sum[cur][2]=(y-x+1)*t2%mod; 69 } 70 void pushdown(int cur,int x,int y) 71 { 72 int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1; 73 if(to[cur]){ 74 //to[ls]=to[rs]=to[cur]; 75 fun_to(ls,x,mid,to[cur]); 76 fun_to(rs,mid+1,y,to[cur]); 77 to[cur]=0; 78 } 79 if(mul[cur]>1){ 80 //mul[ls]*=mul[cur],mul[rs]*=mul[cur]; 81 fun_mul(ls,x,mid,mul[cur]); 82 fun_mul(rs,mid+1,y,mul[cur]); 83 mul[cur]=1; 84 } 85 if(add[cur]){ 86 //add[ls]+=add[cur],add[rs]+=add[cur]; 87 fun_add(ls,x,mid,add[cur]); 88 fun_add(rs,mid+1,y,add[cur]); 89 add[cur]=0; 90 } 91 } 92 void change(int cur,int x,int y,int s,int t,int op,int v) 93 { 94 int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1; 95 if(x>=s&&y<=t){ 96 if(op==1) fun_add(cur,x,y,v); 97 if(op==2) fun_mul(cur,x,y,v); 98 if(op==3) fun_to(cur,x,y,v); 99 return; 100 } 101 pushdown(cur,x,y); 102 if(mid>=s) change(ls,x,mid,s,t,op,v); 103 if(mid+1<=t) change(rs,mid+1,y,s,t,op,v); 104 update(cur); 105 } 106 void query(int cur,int x,int y,int s ,int t,int p,int &ans) 107 { 108 int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1; 109 if(x>=s&&y<=t){ 110 ans+=sum[cur][p-1]; 111 ans%=mod; 112 return; 113 } 114 pushdown(cur,x,y); 115 if(mid>=s) query(ls,x,mid,s,t,p,ans); 116 if(mid+1<=t) query(rs,mid+1,y,s,t,p,ans); 117 } 118 int main() 119 { 120 int n,m,op,x,y,p; 121 while(scanf("%d%d",&n,&m),n+m){ 122 build(1,1,n); 123 for(int i=0;i<m;i++){ 124 scanf("%d%d%d%d",&op,&x,&y,&p); 125 if(op==4){ 126 int ans=0; 127 //printf("%d\n",0); 128 query(1,1,n,x,y,p,ans); 129 printf("%d\n",ans%mod); 130 } 131 else change(1,1,n,x,y,op,p); 132 } 133 } 134 }