题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
大概就是维护两个标记的线段树模板题。
设定优先级,先乘后加(只是相对的),$pushdown$的时候乘法标记直接乘,加法标记先乘上父亲的乘法标记再加上父亲的加法标记。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 1001000 10 #define llg long long 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,md; 13 14 struct SEGMENT_TREE 15 { 16 llg val[maxn],addv[maxn],mul[maxn]; 17 bool bj[maxn]; 18 void init(){memset(val,0,sizeof(val)); memset(mul,1,sizeof(mul)); memset(addv,0,sizeof(addv)); memset(bj,0,sizeof(bj));} 19 20 void build(llg o,llg l,llg r) 21 { 22 if (l==r) 23 { 24 addv[o]=0,mul[o]=1; 25 scanf("%lld",&val[o]); 26 return ; 27 } 28 llg mid=(l+r)>>1,lc=o<<1,rc=o<<1|1; 29 build(lc,l,mid); 30 build(rc,mid+1,r); 31 val[o]=val[lc]+val[rc]; 32 mul[o]=1; addv[o]=0; 33 } 34 35 void pushdown(llg o,llg l,llg r) 36 { 37 llg lc=o<<1,rc=o<<1|1; 38 mul[lc]*=mul[o],mul[lc]%=md; 39 mul[rc]*=mul[o],mul[rc]%=md; 40 addv[lc]*=mul[o],addv[lc]%=md; 41 addv[rc]*=mul[o],addv[rc]%=md; 42 addv[lc]+=addv[o],addv[lc]%=md; 43 addv[rc]+=addv[o],addv[rc]%=md; 44 val[o]=val[o]*mul[o]+addv[o]*(r-l+1); val[o]%=md; 45 addv[o]=0,mul[o]=1; 46 } 47 48 void add_(llg o,llg l,llg r,llg L,llg R,llg V) 49 { 50 pushdown(o,l,r); 51 if (L>r || R<l) return ; 52 if (l>=L && r<=R) 53 { 54 addv[o]+=V; 55 pushdown(o,l,r); 56 return ; 57 } 58 llg mid=(l+r)>>1,lc=o<<1,rc=o<<1|1; 59 add_(lc,l,mid,L,R,V); 60 add_(rc,mid+1,r,L,R,V); 61 val[o]=val[lc]+val[rc]; val[o]%=md; 62 } 63 64 void mul_(llg o,llg l,llg r,llg L,llg R,llg V) 65 { 66 pushdown(o,l,r); 67 if (L>r || R<l) return ; 68 if (l>=L && r<=R) 69 { 70 mul[o]*=V; 71 pushdown(o,l,r); 72 return ; 73 } 74 llg mid=(l+r)>>1,lc=o<<1,rc=o<<1|1; 75 mul_(lc,l,mid,L,R,V); 76 mul_(rc,mid+1,r,L,R,V); 77 val[o]=val[lc]+val[rc]; val[o]%=md; 78 } 79 80 llg sum(llg o,llg l,llg r,llg L,llg R) 81 { 82 pushdown(o,l,r); 83 if (L>r || R<l) return 0; 84 if (l>=L && r<=R) 85 { 86 return val[o]; 87 } 88 llg mid=(l+r)>>1,lc=o<<1,rc=o<<1|1,tot=0; 89 tot+=sum(lc,l,mid,L,R); 90 tot+=sum(rc,mid+1,r,L,R); 91 val[o]=val[lc]+val[rc]; val[o]%=md; 92 return tot%md; 93 } 94 95 }tree; 96 97 int main() 98 { 99 tree.init(); 100 yyj("a"); 101 cin>>n>>md; 102 tree.build(1,1,n); 103 llg T,type,l,r,v; 104 cin>>T; 105 while (T--) 106 { 107 scanf("%lld",&type); 108 if (type==1) 109 { 110 scanf("%lld%lld%lld",&l,&r,&v); 111 tree.mul_(1,1,n,l,r,v); 112 } 113 if (type==2) 114 { 115 scanf("%lld%lld%lld",&l,&r,&v); 116 tree.add_(1,1,n,l,r,v); 117 } 118 if (type==3) 119 { 120 scanf("%lld%lld",&l,&r); 121 printf("%lld ",tree.sum(1,1,n,l,r)); 122 } 123 } 124 return 0; 125 }