如題,已知一個數列,你須要進行下面三種操做:node
1.將某區間每個數乘上xios
2.將某區間每個數加上xide
3.求出某區間每個數的和ui
輸入格式:spa
第一行包含三個整數N、M、P,分別表示該數列數字的個數、操做的總個數和模數。code
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。blog
接下來M行每行包含3或4個整數,表示一個操做,具體以下:get
操做1: 格式:1 x y k 含義:將區間[x,y]內每一個數乘上kio
操做2: 格式:2 x y k 含義:將區間[x,y]內每一個數加上kevent
操做3: 格式:3 x y 含義:輸出區間[x,y]內每一個數的和對P取模所得的結果
輸出格式:
輸出包含若干行整數,即爲全部操做3的結果。
時空限制:1000ms,128M
數據規模:
對於30%的數據:N<=8,M<=10
對於70%的數據:N<=1000,M<=10000
對於100%的數據:N<=100000,M<=100000
(數據已通過增強^_^)
樣例說明:
故輸出應爲1七、2(40 mod 38=2)
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,m,p,judge,x,y,k; 5 long long a[100007]; 6 long long read() 7 { 8 long long x=0,f=1; 9 char ch=getchar(); 10 while(ch>'9'||ch<'0') 11 { 12 if(ch=='-') 13 f=-1; 14 ch=getchar(); 15 } 16 while(ch>='0'&&ch<='9') 17 { 18 x=x*10+ch-'0'; 19 ch=getchar(); 20 } 21 return x*f; 22 } 23 struct node 24 { 25 long long v,mul,add; 26 } st[400007]; 27 void build(int root, int l, int r) 28 { 29 st[root].mul=1; 30 st[root].add=0; 31 if(l==r) 32 st[root].v=a[l]; 33 else 34 { 35 int m=(l+r)/2; 36 build(root*2, l, m); 37 build(root*2+1, m+1, r); 38 st[root].v=st[root*2].v+st[root*2+1].v; 39 } 40 st[root].v%=p; 41 return ; 42 } 43 void pushdown(int root, int l, int r) 44 { 45 int m=(l+r)/2; 46 st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(m-l+1))%p; 47 st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(r-m))%p; 48 st[root*2].mul=(st[root*2].mul*st[root].mul)%p; 49 st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p; 50 st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p; 51 st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p; 52 st[root].mul=1; 53 st[root].add=0; 54 return ; 55 } 56 void up(int root,int stdl,int stdr,int l,int r,long long k) 57 { 58 if(r<stdl||stdr<l) 59 return ; 60 if(l<=stdl&&stdr<=r) 61 { 62 st[root].v=(st[root].v*k)%p; 63 st[root].mul=(st[root].mul*k)%p; 64 st[root].add=(st[root].add*k)%p; 65 return ; 66 } 67 pushdown(root, stdl, stdr); 68 int m=(stdl+stdr)/2; 69 up(root*2,stdl,m,l,r,k); 70 up(root*2+1,m+1,stdr,l,r,k); 71 st[root].v=(st[root*2].v+st[root*2+1].v)%p; 72 return ; 73 } 74 void date(int root,int stdl,int stdr,int l,int r,long long k) 75 { 76 if(r<stdl||stdr<l) 77 return ; 78 if(l<=stdl&&stdr<=r) 79 { 80 st[root].add=(st[root].add+k)%p; 81 st[root].v=(st[root].v+k*(stdr-stdl+1))%p; 82 return ; 83 } 84 pushdown(root,stdl,stdr); 85 int m=(stdl+stdr)/2; 86 date(root*2,stdl,m,l,r,k); 87 date(root*2+1,m+1,stdr,l,r,k); 88 st[root].v=(st[root*2].v+st[root*2+1].v)%p; 89 return ; 90 } 91 long long query(int root,int stdl,int stdr,int l,int r) 92 { 93 if(r<stdl||stdr<l) 94 return 0; 95 if(l<=stdl&&stdr<=r) 96 return st[root].v; 97 pushdown(root,stdl,stdr); 98 int m=(stdl+stdr)/2; 99 return (query(root*2,stdl,m,l,r)+query(root*2+1,m+1,stdr,l,r))%p; 100 } 101 int main() 102 { 103 n=read(),m=read(),p=read(); 104 for(int i=1; i<=n; i++) 105 a[i]=read(); 106 build(1,1,n); 107 while(m--) 108 { 109 judge=read(); 110 if(judge==1) 111 { 112 x=read(),y=read(),k=read(); 113 up(1,1,n,x,y,k); 114 } 115 else if(judge==2) 116 { 117 x=read(),y=read(),k=read(); 118 date(1,1,n,x,y,k); 119 } 120 else 121 { 122 x=read(),y=read(); 123 printf("%lld\n", query(1,1,n,x,y)); 124 } 125 } 126 return 0; 127 }