洛谷P2023 [AHOI2009]维护序列 线段树

洛谷P2023 [AHOI2009]维护序列

线段树 带乘法标记 和 加法标记
处理两个标记时记得要两个标记之间互不影响,
如果有影响,则要改变一下

我们一律先处理乘法标记 在处理加法标记
如果已经有了加法标记 又来了一个乘法标记
那么加法 标记也要乘 否则就不能做到强制先后了
这样就能保证标记之间互不影响

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream> 
  8 #include <iomanip>
  9 #define ll long long  
 10 using namespace std ; 
 11 
 12 const int maxn = 100011 ; 
 13 
 14 struct node{
 15     int l,r ;
 16     ll sum,ADD,MUL ; 
 17 }tree[maxn*4];
 18 int n,Q ; 
 19 ll ans,v,mod ; 
 20 int a[maxn] ; 
 21 
 22 inline ll read() 
 23 {
 24     char ch = getchar() ; 
 25     ll  x=0,f=1 ; 
 26     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
 27     while(ch>='0'&&ch<='9') { x = x*10+ch-48 ; ch = getchar() ; } 
 28     return x * f ; 
 29 }
 30 
 31 inline void write(ll x) 
 32 {
 33     if(x<0) x = -x,putchar('-') ; 
 34     if(x>9) write(x/10) ; 
 35     putchar(x % 10 + 48 ) ;    
 36 }  
 37 
 38 inline void writeln(ll x )  { write(x) ; putchar('
') ; }  
 39 inline void pushup(int root) 
 40 {
 41     tree[root].sum = ( tree[root<<1].sum + tree[root<<1|1].sum ) %mod ; 
 42 }
 43 
 44 inline void build(int root,int l,int r) 
 45 {
 46     tree[root].l = l ;  tree[root].r = r ;  
 47     tree[root].MUL = 1 ;tree[root].ADD = 0 ; 
 48     if(l==r) 
 49     {
 50         tree[root].sum = a[ l ] ;
 51         return ;  
 52     }
 53     int mid = (l+r) /2 ; 
 54     build(root<<1,l,mid) ; 
 55     build(root<<1|1,mid+1,r) ; 
 56     pushup(root) ; 
 57 }
 58 
 59 inline void pushdown(int root) 
 60 {
 61     if(tree[root].MUL==1&&tree[root].ADD==0) return ; 
 62     tree[root<<1].ADD =  ( tree[root<<1].ADD * tree[root].MUL +tree[root].ADD ) %mod ; 
 63     tree[root<<1|1].ADD = (tree[root<<1|1].ADD*tree[root].MUL +tree[root].ADD ) %mod ; 
 64     
 65     tree[root<<1].MUL = tree[root<<1].MUL * tree[root].MUL % mod ; 
 66     tree[root<<1|1].MUL = tree[root<<1|1].MUL*tree[root].MUL % mod ; 
 67     
 68     tree[root<<1].sum=( tree[root<<1].sum * tree[root].MUL + tree[root].ADD *(tree[root<<1].r-tree[root<<1].l+1)  ) % mod;
 69     tree[root<<1|1].sum=( tree[root<<1|1].sum*tree[root].MUL + tree[root].ADD *(tree[root<<1|1].r-tree[root<<1|1].l+1)  ) % mod;
 70     tree[root].MUL = 1 ; 
 71     tree[root].ADD = 0 ;  
 72 }
 73 
 74 inline void updata(int root,int l,int r,ll mul,ll add) 
 75 {
 76     if(tree[root].l==l&&tree[root].r==r) 
 77     {
 78         tree[root].ADD = (  tree[root].ADD * mul + add )  % mod ; 
 79         tree[root].MUL = tree[root].MUL * mul % mod ; 
 80         tree[root].sum = ( tree[root].sum*mul  + (tree[root].r-tree[root].l+1) * add ) %mod ;  
 81         return ; 
 82     }
 83     pushdown(root) ; 
 84     int mid = (tree[root].l + tree[root].r) /2 ; 
 85     if( r<=mid ) updata(root<<1,l,r,mul,add) ; 
 86     else if( l>mid )  updata(root<<1|1,l,r,mul,add) ; 
 87     else 
 88     {
 89         updata(root<<1,l,mid,mul,add) ; 
 90         updata(root<<1|1,mid+1,r,mul,add) ; 
 91     }
 92     pushup(root) ; 
 93 }
 94 
 95 inline ll query(int root,int l,int r) 
 96 {
 97     if(tree[root].l==l&&tree[root].r==r) 
 98         return tree[root].sum ; 
 99     pushdown(root) ; 
100     
101     int mid = (tree[root].l + tree[root].r) /2 ; 
102     if( r<=mid ) return query(root<<1,l,r)  ; 
103     if( l>mid )  return query(root<<1|1,l,r) ; 
104     ll ans = 0 ; 
105     ans = (ans+query(root<<1,l,mid)) %mod ; 
106     ans = (ans+query(root<<1|1,mid+1,r)) %mod ; 
107     return ans ;     
108 }
109 
110 int main() 
111 {
112     n = read() ; mod = read() ; 
113     for(int i=1;i<=n;i++) 
114         a[ i ] = read(),a[ i ] %=mod ; 
115     build(1,1,n) ; 
116     Q = read() ; 
117     int type,l,r ; 
118     for(int i=1;i<=Q;i++) 
119     {
120         type = read() ; l = read() ;  r = read() ; 
121         if(type==1) 
122         {
123             v = read() ;  v%=mod ; 
124             updata(1,l,r,v,0) ;  
125         }
126         if(type==2) 
127         {
128             v = read() ; v%=mod ; 
129             updata(1,l,r,1,v) ; 
130         } 
131         if(type==3) 
132         {
133             ans = query(1,l,r) %mod ; 
134             writeln( ans ) ; 
135         }
136     } 
137     
138      return 0 ; 
139 }
原文地址:https://www.cnblogs.com/third2333/p/7095137.html