• 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
    ",query(t,g,1)%P);
    66 } 
    View Code
  • 相关阅读:
    iframe透明
    c#创建可以为空类型
    div仿框架布局
    IBatis.Net学习笔记(六):Castle.DynamicProxy的使用
    很好玩的谷歌纵横
    TFS签入签出规范
    ibatis学习笔记
    iBATIS.net调用存储过程
    最新28个很棒的 jQuery 教程
    IBatis.Net 中的数据类型转换
  • 原文地址:https://www.cnblogs.com/mczhuang/p/7718570.html
Copyright © 2020-2023  润新知