bzoj1798 [Ahoi2009]Seq 维护序列seq 线段树

此题甚坑,一开始我一直怀疑线段树敲渣了,最后发现又没开longlong     QAQ

我居然蠢蠢地连改了几个无关紧要的东西疯狂地交

过了以后看到网上大神的左右儿子都用define写,表示羡慕,开始改程序(MDZZ还RE了一遍),希望以后再写线段树的时候能记得用define缩代码减少点错误

主要是标记的变化(增加或下移)时乘法一定要转移全(标记和树上维护的和都要更新)

其他就是简单的裸线段树(其实整个就是裸的,只是智障症犯了)

  1 #include <cstdio>
  2 #define lson l,mid,now<<1
  3 #define rson mid+1,r,now<<1|1
  4 #define N 100010
  5 using namespace std;
  6 typedef long long ll;
  7 ll mul[N<<2],sum[N<<2],add[N<<2];
  8 int n,mod,q,opt,x,y;
  9 void pushup(int now)
 10 {
 11     sum[now]=(sum[now<<1]+sum[now<<1|1])%mod;
 12 }
 13 void pushdown(int now,ll m)
 14 {
 15     if(mul[now]!=1||add[now]!=0)
 16     {
 17         mul[now<<1]=(mul[now<<1]*mul[now])%mod;
 18         mul[now<<1|1]=(mul[now<<1|1]*mul[now])%mod;
 19         add[now<<1]=(mul[now]*add[now<<1]+add[now])%mod;
 20         add[now<<1|1]=(mul[now]*add[now<<1|1]+add[now])%mod;
 21         sum[now<<1]=(sum[now<<1]*mul[now]+(m-(m>>1))*add[now])%mod;
 22         sum[now<<1|1]=(sum[now<<1|1]*mul[now]+(m>>1)*add[now])%mod;
 23         mul[now]=1,add[now]=0;
 24     }
 25 }
 26 void build(int l,int r,int now)
 27 {
 28     mul[now]=1,sum[now]=0;
 29     if(l==r)
 30     {
 31         scanf("%I64d",&sum[now]);
 32         return;
 33     }
 34     int mid=(l+r)>>1;
 35     build(lson),build(rson);
 36     pushup(now);
 37 }
 38 void _mul(int L,int R,int l,int r,int now,ll c)
 39 {
 40     if(L<=l&&r<=R)
 41     {
 42         mul[now]=(mul[now]*c)%mod;
 43         add[now]=(add[now]*c)%mod;
 44         sum[now]=(sum[now]*c)%mod;
 45         return;
 46     }
 47     pushdown(now,r-l+1);
 48     int mid=(l+r)>>1;
 49     if(L<=mid)_mul(L,R,lson,c);
 50     if(R>mid) _mul(L,R,rson,c);
 51     pushup(now);
 52 }
 53 void _add(int L,int R,int l,int r,int now,ll c)
 54 {
 55     if(L<=l&&r<=R)
 56     {
 57         add[now]=(add[now]+c)%mod;
 58         sum[now]=(sum[now]+(r-l+1)*c)%mod;
 59         return;
 60     }
 61     pushdown(now,r-l+1);
 62     int mid=(l+r)>>1;
 63     if(L<=mid)
 64         _add(L,R,lson,c);
 65     if(R>mid)
 66         _add(L,R,rson,c);
 67     pushup(now);
 68 }
 69 ll query(int L,int R,int l,int r,int now)
 70 {
 71     if(L<=l&&r<=R)
 72     {
 73         return sum[now];
 74     }
 75     pushdown(now,r-l+1);
 76     int mid=(l+r)>>1;
 77     ll ans=0;
 78     if(L<=mid)
 79         ans=(ans+query(L,R,lson))%mod;
 80     if(R>mid)
 81         ans=(ans+query(L,R,rson))%mod;
 82     pushup(now);
 83     return ans;
 84 }
 85 int main()
 86 {
 87     scanf("%d%d",&n,&mod);
 88     build(1,n,1);
 89     scanf("%d",&q);
 90     while(q--)
 91     {
 92         scanf("%d",&opt);
 93         scanf("%d%d",&x,&y);
 94         int z;
 95         switch(opt)
 96         {
 97             case 1:scanf("%d",&z);_mul(x,y,1,n,1,z);break;
 98             case 2:scanf("%d",&z);_add(x,y,1,n,1,z);break;
 99             case 3:printf("%lld\n",query(x,y,1,n,1));break;
100         }
101     }
102 }

 

posted @ 2016-07-19 16:04  汪立超  阅读(269)  评论(0编辑  收藏  举报