洛谷P3373 【模板】线段树 2
题目描述
如题,已知一个数列,你需要进行下面三种操作:
1.将某区间每一个数乘上x
2.将某区间每一个数加上x
3.求出某区间每一个数的和
输入格式
第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k
操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k
操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果
输出格式
输出包含若干行整数,即为所有操作3的结果。
输入输出样例
输入 #15 5 38 1 5 4 2 3 2 1 4 1 3 2 5 1 2 4 2 2 3 5 5 3 1 4输出 #117 2说明/提示
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^)
啊调这道水体调了一晚上果然我太弱了qaqq
附上代码
1 #include<bits/stdc++.h> 2 #define re register int 3 #define LL long long 4 #define lson now<<1 5 #define rson now<<1|1 6 #define maxn 1000000+5 7 8 using namespace std; 9 int n,m,mod,op,x,y,k; 10 LL num[maxn]; 11 struct tree{ 12 LL sum,add,mul; 13 }tr[maxn<<2]; 14 void build(int now,int l,int r) 15 { 16 tr[now].add=0; 17 tr[now].mul=1; 18 if(l==r) 19 { 20 tr[now].sum=num[l]; 21 return; 22 } 23 int mid=(l+r)>>1; 24 build(lson,l,mid); 25 build(rson,mid+1,r); 26 tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod; 27 //显然不用加tr[now].sum 28 } 29 void lazy(int now,int l,int r) 30 { 31 int mid=(l+r)>>1; 32 tr[lson].sum=(tr[lson].sum*tr[now].mul%mod+tr[now].add*(mid-l+1)%mod)%mod; 33 tr[rson].sum=(tr[rson].sum*tr[now].mul%mod+tr[now].add*(r-mid)%mod)%mod; 34 tr[lson].mul=(tr[lson].mul*tr[now].mul)%mod; 35 tr[rson].mul=(tr[rson].mul*tr[now].mul)%mod; 36 tr[lson].add=(tr[lson].add*tr[now].mul%mod+tr[now].add)%mod; 37 tr[rson].add=(tr[rson].add*tr[now].mul%mod+tr[now].add)%mod; 38 //记得要乘tr[now].mul鸭 39 tr[now].add=0; 40 tr[now].mul=1; 41 } 42 void refresh(int now,int L,int R,int l,int r,LL mu) 43 { 44 // if(l>R||r<L) 45 // return; 46 if(L<=l&&R>=r) 47 { 48 tr[now].sum=(tr[now].sum*mu)%mod; 49 tr[now].add=(tr[now].add*mu)%mod; 50 tr[now].mul=(tr[now].mul*mu)%mod; 51 return; 52 } 53 lazy(now,l,r); 54 int mid=(l+r)>>1; 55 if(L<=mid) refresh(lson,L,R,l,mid,mu); 56 if(R>mid) refresh(rson,L,R,mid+1,r,mu); 57 tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod; 58 } 59 void refresh2(int now,int L,int R,int l,int r,int ad) 60 { 61 // if(l>R||r<L) 62 // return; 63 // cout<<l<<" "<<r<<" "<<tr[now].sum<<endl; 64 if(L<=l&&R>=r) 65 { 66 // cout<<(r-l+1)<<endl; 67 // cout<<tr[now].sum<<endl; 68 // cout<<ad<<endl; 69 tr[now].sum=(tr[now].sum+ad*(r-l+1)%mod)%mod; 70 tr[now].add=(tr[now].add+ad)%mod; 71 // cout<<tr[now].sum<<" "<<tr[now].add<<endl; 72 return; 73 } 74 lazy(now,l,r); 75 int mid=(l+r)>>1; 76 // cout<<L<<" "<<R<<endl; 77 if(L<=mid) refresh2(lson,L,R,l,mid,ad);//不要再写错函数名了 78 if(R>mid) refresh2(rson,L,R,mid+1,r,ad); 79 tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod; 80 } 81 LL query(int now,int l,int r,int L,int R) 82 { 83 // if(L>r||R<l) 84 // return 0; 85 // cout<<l<<" "<<r<<" "<<tr[now].sum<<endl; 86 if(L<=l&&R>=r) 87 return tr[now].sum%mod; 88 lazy(now,l,r); 89 int mid=(l+r)>>1; 90 if(L>mid) return query(rson,mid+1,r,L,R)%mod; 91 else if(R<=mid) 92 return query(lson,l,mid,L,R)%mod; 93 else return (query(lson,l,mid,L,R)+query(rson,mid+1,r,L,R))%mod; 94 } 95 int main() 96 { 97 ios::sync_with_stdio(false); 98 cin>>n>>m>>mod; 99 for(re i=1;i<=n;i++) 100 cin>>num[i],num[i]%=mod; 101 build(1,1,n); 102 while(m--) 103 { 104 cin>>op; 105 if(op==1) 106 { 107 cin>>x>>y>>k; 108 refresh(1,x,y,1,n,k); 109 } 110 if(op==2) 111 { 112 cin>>x>>y>>k; 113 refresh2(1,x,y,1,n,k); 114 } 115 if(op==3) 116 { 117 cin>>x>>y; 118 cout<<query(1,1,n,x,y)<<endl; 119 } 120 } 121 return 0; 122 }
We're the lovers above the city.