bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=1798

题意:

题解:

线段树,区间乘法+区间加法,都扔给一个updata就好

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 #define MS(a) memset(a,0,sizeof(a))
  5 #define MP make_pair
  6 #define PB push_back
  7 const int INF = 0x3f3f3f3f;
  8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
  9 inline ll read(){
 10     ll x=0,f=1;char ch=getchar();
 11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 13     return x*f;
 14 }
 15 //////////////////////////////////////////////////////////////////////////
 16 const int maxn = 1e5+10;
 17 
 18 ll a[maxn],mod,ans[maxn];
 19 
 20 struct node{
 21     int l,r;
 22     ll sum,add,mul,lazy;
 23     void update(int a,int m,int len){
 24         add = ((ll)(add*m+a))%mod;
 25         mul = ((ll)(m*mul))%mod;
 26         sum = ((ll)((ll)sum*m+(ll)len*a))%mod;
 27     }
 28 }tree[maxn<<2];
 29 
 30 void pushup(int rt){
 31     tree[rt].sum = (tree[rt<<1].sum + tree[rt<<1|1].sum) % mod;
 32 }
 33 
 34 void pushdown(int rt,int len){
 35     if(tree[rt].add!=0 || tree[rt].mul!=1){
 36         tree[rt<<1].update(tree[rt].add,tree[rt].mul,len-(len>>1));
 37         tree[rt<<1|1].update(tree[rt].add,tree[rt].mul,len>>1);
 38         tree[rt].add = 0; tree[rt].mul = 1;
 39     }
 40 }
 41 
 42 
 43 void build(int rt,int l,int r){
 44     tree[rt].l = l, tree[rt].r = r;
 45     tree[rt].add = 0, tree[rt].mul = 1;
 46     if(l == r) {
 47         tree[rt].sum = a[l];
 48         return ;
 49     }
 50     int mid = (l+r)/2;
 51     build(rt<<1,l,mid);
 52     build(rt<<1|1,mid+1,r);
 53     pushup(rt);
 54 }
 55 
 56 void update(int rt,int l,int r,int add,int mul){
 57     int L = tree[rt].l, R = tree[rt].r;
 58     if(l<=L && R<=r){
 59         tree[rt].update(add,mul,R-L+1);
 60         return ;
 61     }
 62     pushdown(rt,R-L+1);
 63     int mid = (L+R)/2;
 64     if(l<=mid) update(rt<<1,l,r,add,mul);
 65     if(r>mid) update(rt<<1|1,l,r,add,mul);
 66     pushup(rt);
 67 }
 68 
 69 ll query(int rt,int l,int r){
 70     int L = tree[rt].l, R = tree[rt].r;
 71     if(l<=L && R<=r)
 72         return tree[rt].sum;
 73     else{
 74         ll ans = 0;
 75         pushdown(rt,R-L+1);
 76         int mid = (L+R)/2;
 77         if(l<=mid) ans = ((ll)(ans+query(rt<<1,l,r)))%mod;
 78         if(r>mid) ans = ((ll)(ans+query(rt<<1|1,l,r)))%mod;
 79         pushup(rt);
 80         return ans;
 81     }
 82 }
 83 
 84 int main(){
 85     int n=read(); 
 86     mod = read();
 87     for(int i=1; i<=n; i++){
 88         a[i] = read();
 89     }
 90     build(1,1,n);
 91     int m = read();
 92     while(m--){
 93         int op = read();
 94         if(op == 1){
 95             int a=read(),b=read(),x=read();
 96             update(1,a,b,0,x);
 97         }else if(op == 2){
 98             int a=read(),b=read(),add=read();
 99             update(1,a,b,add,1);
100         }else{
101             int a=read(),b=read();
102             printf("%lld\n",query(1,a,b)%mod);
103         }
104     }
105 
106     return 0;
107 }

 

posted @ 2017-03-02 16:43  _yxg123  阅读(159)  评论(0编辑  收藏  举报