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

线段树维护sum值并记录add与mult用于标记下传+乘法结合律

 1 #include <cstdio>
 2 #define ll long long
 3 inline int read()
 4 {
 5     register int k=0,f=1;register char c=getchar();
 6     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
 7     while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
 8     return k*f; 
 9 }
10 struct node{int l,r;ll delta,sum,mult;}tree[8*(100000+10)];
11 ll m,P;
12 inline void pushup(int cur){tree[cur].sum=(tree[cur<<1].sum+tree[cur<<1|1].sum)%P;}
13 inline void pushdown(int cur)
14 {
15     tree[cur<<1].delta=(tree[cur<<1].delta*tree[cur].mult+tree[cur].delta)%P;
16     tree[cur<<1|1].delta=(tree[cur<<1|1].delta*tree[cur].mult+tree[cur].delta)%P;
17     tree[cur<<1].sum=(tree[cur<<1].sum*tree[cur].mult+tree[cur].delta*(tree[cur<<1].r-tree[cur<<1].l+1))%P;
18     tree[cur<<1|1].sum=(tree[cur<<1|1].sum*tree[cur].mult+tree[cur].delta*(tree[cur<<1|1].r-tree[cur<<1|1].l+1))%P;
19     tree[cur<<1].mult=tree[cur<<1].mult*tree[cur].mult%P;
20     tree[cur<<1|1].mult=tree[cur<<1|1].mult*tree[cur].mult%P;
21     tree[cur].mult=1;tree[cur].delta=0;
22 }
23 ll query(int l,int r,int cur)
24 {
25     if (l<=tree[cur].l&&tree[cur].r<=r)return tree[cur].sum%P;
26     register int mid=(tree[cur].l+tree[cur].r)>>1;register ll tmp=0;
27     pushdown(cur);
28     if (l<=mid)tmp=query(l,r,cur<<1);
29     if (r>mid)tmp+=query(l,r,cur<<1|1);
30     pushup(cur);
31     return tmp;
32 }
33 void update(int l,int r,ll add,ll mul,int cur)
34 {
35     if (l<=tree[cur].l&&tree[cur].r<=r)
36     {
37         tree[cur].sum=(tree[cur].sum*mul+add*(tree[cur].r-tree[cur].l+1))%P;
38         tree[cur].delta=tree[cur].delta*mul%P;
39         tree[cur].mult=tree[cur].mult*mul%P;
40         tree[cur].delta=(tree[cur].delta+add)%P;
41         return;
42     }
43     register int mid=(tree[cur].l+tree[cur].r)>>1;
44     pushdown(cur);
45     if (l<=mid)update(l,r,add,mul,cur<<1);
46     if (r>mid)update(l,r,add,mul,cur<<1|1);
47     pushup(cur);
48 }
49 int build(int l,int r,int cur)
50 {
51     if ((tree[cur].l=l)==(tree[cur].r=r))return tree[cur].sum=read()%P;
52     build(l,(l+r)>>1,cur<<1);
53     build(((l+r)>>1)+1,r,cur<<1|1);
54     pushup(cur);
55     tree[cur].mult=1;
56 }
57 int main()
58 {
59     register int tmp,t,g,c,n=read();P=read();
60     build(1,n,1);
61     m=read();
62     for (register int i=1;i<=m;i++)
63     if ((tmp=read())==1)t=read(),g=read(),c=read(),update(t,g,0,c%P,1);
64     else if (tmp==2)t=read(),g=read(),c=read(),update(t,g,c%P,1,1);
65     else t=read(),g=read(),printf("%lld\n",query(t,g,1)%P);
66 } 
View Code

 

posted @ 2017-10-23 19:39  Michael_Zhuang  阅读(176)  评论(0编辑  收藏  举报