bzoj1798: [Ahoi2009]Seq 维护序列seq

来源:互联网 发布:福建网络广播电视台:{ 编辑:程序博客网 时间:2024/06/09 15:02

传送门
裸的线段树,每个节点打标记add和mul,注意下传即可。

#include<cmath>#include<cstdio>  #include<cstdlib>#include<cstring>  #include<iostream>#include<algorithm>#define ll long long   using namespace std;  const int N=100010;  struct node{      int L,R;      ll sum,add,mul;  }t[N*4];  int a[N],mo,n,m;  void pushup(int p){      t[p].sum=(t[p<<1].sum+t[p<<1|1].sum)%mo;  }  void update1(int p,ll d){      int len=t[p].R-t[p].L+1;      t[p].sum=(t[p].sum+d*len%mo)%mo;      t[p].add=(t[p].add+d)%mo;  }  void update2(int p,ll d){      t[p].sum=(t[p].sum*d)%mo;      t[p].add=(t[p].add*d)%mo;      t[p].mul=(t[p].mul*d)%mo;  }  void pushdown(int p){      update2(p<<1,t[p].mul);      update2(p<<1|1,t[p].mul);      t[p].mul=1;      update1(p<<1,t[p].add);      update1(p<<1|1,t[p].add);      t[p].add=0;  }  void build(int p,int L,int R){      if(L==R){          t[p].L=t[p].R=L;          t[p].sum=a[L];          t[p].add=0;          t[p].mul=1;          return;      }      int mid=L+R>>1;      build(p<<1,L,mid);      build(p<<1|1,mid+1,R);      t[p].L=L;      t[p].R=R;      t[p].mul=1;      t[p].add=0;      pushup(p);  }  void add(int p,int L,int R,int d){      int n_L=t[p].L;      int n_R=t[p].R;      if(L<=n_L && n_R<=R){          update1(p,d);          return;      }      pushdown(p);      int mid=n_L+n_R>>1;      if(L<=mid)add(p<<1,L,R,d);      if(mid<R)add(p<<1|1,L,R,d);      pushup(p);  }  void mul(int p,int L,int R,int d){      int n_L=t[p].L;      int n_R=t[p].R;      if(L<=n_L && n_R<=R){          update2(p,d);          return;      }      pushdown(p);      int mid=n_L+n_R>>1;      if(L<=mid)mul(p<<1,L,R,d);      if(mid<R)mul(p<<1|1,L,R,d);      pushup(p);  }  int sum(int p,int L,int R){      int n_L=t[p].L;      int n_R=t[p].R;      if(L<=n_L && n_R<=R)return t[p].sum;      pushdown(p);      int mid=n_L+n_R>>1;      ll ret=0;      if(L<=mid)ret=(ret+sum(p<<1,L,R))%mo;      if(mid<R) ret=(ret+sum(p<<1|1,L,R))%mo;      return ret;  }  int main(){      scanf("%d%d",&n,&mo);      for(int i=1;i<=n;i++)scanf("%d",&a[i]);      build(1,1,n);       scanf("%d",&m);      for(int i=1;i<=m;i++){          int fg,L,R,d;          scanf("%d",&fg);          switch(fg){              case 1:{                  scanf("%d%d%d",&L,&R,&d);                  mul(1,L,R,d);                  break;              }              case 2:{                  scanf("%d%d%d",&L,&R,&d);                  add(1,L,R,d);                  break;              }              case 3:{                  scanf("%d%d",&L,&R);                  printf("%d\n",sum(1,L,R));                  break;              }          }      }  }  
原创粉丝点击