【BZOJ】1798: [Ahoi2009]Seq 维护序列seq

题目链接: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\n",tree.sum(1,1,n,l,r));
122         }
123     }
124     return 0;
125 }

 

posted @ 2017-03-07 21:38  №〓→龙光←  阅读(181)  评论(0编辑  收藏  举报