• bzoj 1798 维护序列seq


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798

    题解:

      高级一点的线段树,加上了区间乘法运算,则需要增加一个数组mulv记录乘的因数,在下放更新sumv和addv值的都时候要先乘再加

      被蓝书的写法坑了,就一直搞不懂下放和sumv、addv数组的具体用法,导致网上大犇们的程序我基本都看不懂,写完这道题感觉重新学了一遍线段树

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 400010
     4 #define LL long long
     5 LL MOD,sumv[MAXN],addv[MAXN],mulv[MAXN];
     6 int n,m,t1,y1,y2,v;
     7 void maintain(int o,int len)//下放 
     8 {
     9     int lc=o<<1,rc=(o<<1)+1,M=len>>1;
    10     if(mulv[o]!=1||addv[o])
    11     {
    12         mulv[lc]=(mulv[lc]*mulv[o])%MOD;
    13         mulv[rc]=(mulv[rc]*mulv[o])%MOD;
    14         addv[lc]=((addv[lc]*mulv[o])+addv[o])%MOD;
    15         addv[rc]=((addv[rc]*mulv[o])+addv[o])%MOD;
    16         sumv[lc]=(sumv[lc]*mulv[o]+(len-M)*addv[o])%MOD;
    17         sumv[rc]=(sumv[rc]*mulv[o]+M*addv[o])%MOD;
    18     }
    19     addv[o]=0;
    20     mulv[o]=1;
    21 }
    22 void build(int o,int L,int R)
    23 {
    24     int lc=o<<1,rc=(o<<1)+1,M=(L+R)/2;
    25     if(L==R)
    26     {
    27         scanf("%lld",&sumv[o]);
    28         return;
    29     }
    30     build(lc,L,M);
    31     build(rc,M+1,R);
    32     sumv[o]=(sumv[lc]+sumv[rc])%MOD;
    33 }
    34 void update(int o,int L,int R)
    35 {
    36     int lc=o<<1,rc=(o<<1)+1,M=(L+R)/2;
    37     if(y1<=L&&y2>=R)
    38     {
    39         if(t1==1)
    40         {
    41             addv[o]=(addv[o]*v)%MOD;
    42             sumv[o]=(sumv[o]*v)%MOD;
    43             mulv[o]=(mulv[o]*v)%MOD;
    44         }
    45         else
    46         {
    47             addv[o]=(addv[o]+v)%MOD;
    48             sumv[o]=(sumv[o]+v*(R-L+1))%MOD;
    49         }
    50         return;
    51     }
    52     maintain(o,R-L+1);
    53     if(y1<=M)update(lc,L,M);
    54     if(y2>M)update(rc,M+1,R);
    55     sumv[o]=(sumv[lc]+sumv[rc])%MOD;
    56 }
    57 LL query(int o,int L,int R)
    58 {
    59     int lc=o<<1,rc=(o<<1)+1,M=(L+R)>>1;
    60     if(y1<=L&&y2>=R)return sumv[o]%MOD;
    61     maintain(o,R-L+1);
    62     LL ans=0;
    63     if(y1<=M)ans=(query(lc,L,M))%MOD;
    64     if(y2>M)ans+=(query(rc,M+1,R))%MOD;
    65     sumv[o]=(sumv[lc]+sumv[rc])%MOD;
    66     return ans%MOD;
    67 }
    68 int main()
    69 {
    70     scanf("%d%lld",&n,&MOD);
    71     for(int i=1;i<=400009;i++)mulv[i]=1;
    72     build(1,1,n);
    73     scanf("%d",&m);
    74     while(m--)
    75     {
    76         scanf("%d%d%d",&t1,&y1,&y2);
    77         if(t1!=3)
    78         {
    79             scanf("%d",&v);
    80             update(1,1,n);
    81         }
    82         else printf("%lld
    ",query(1,1,n));
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    go语言基础之map赋值、遍历、删除 、做函数参数
    go语言基础之map介绍和使用
    go语言基础之go猜数字游戏
    go语言基础之切片做函数参数
    ORA-28001: the password has expired解决方法
    windows10下设置Maven的本地仓库和阿里云的远程中央仓库
    mvn安装
    elk基于jolokia监控springboot应用jvm方案
    陌陌风控系统
    ElasticSearch SIEM方案
  • 原文地址:https://www.cnblogs.com/xqmmcqs/p/5967762.html
Copyright © 2020-2023  润新知