• 【BZOJ】【1798】【AHOI2009】Seq维护序列


    线段树

      属于线段树中级应用吧……

      要打两种标记:乘法和加法标记。一开始我想着可以像只有加法标记那样,永不下传,查询的时候依次累加就好了。后来发现不会写……只好每次update的时候……遇到标记!下传!query的时候遇到标记!下传!暴力地来搞……

      然后说下下传的细节:先传乘法,后传加法。因为传乘法标记的时候要连sum带add都要一起乘,如果先传add就会多乘……

      1 /**************************************************************
      2     Problem: 1798
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:3868 ms
      7     Memory:6748 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 1798
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define rep(i,n) for(int i=0;i<n;++i)
     17 #define F(i,j,n) for(int i=j;i<=n;++i)
     18 #define D(i,j,n) for(int i=j;i>=n;--i)
     19 //using namespace std;
     20 const int N=100086;
     21 typedef long long LL;
     22 //#define debug
     23 int n,m,P,a[N];
     24 int mul[N<<2],add[N<<2],sum[N<<2];
     25  
     26 void read(int &v){
     27     v=0; int sign=1; char ch=getchar();
     28     while(ch<'0' || ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     29     while(ch>='0' && ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     30     v*=sign;
     31 }
     32 #define mid (l+r>>1)
     33 #define L (o<<1)
     34 #define R (o<<1|1)
     35  
     36 void Push_down(int o,int l,int r){
     37     if (mul[o]!=1){
     38         add[L]=((LL)add[L]*mul[o])%P; add[R]=((LL)add[R]*mul[o])%P;
     39         mul[L]=((LL)mul[L]*mul[o])%P; mul[R]=((LL)mul[R]*mul[o])%P;
     40         mul[o]=1;
     41     }
     42     if (add[o]!=0){
     43         add[L]=((LL)add[L]+add[o])%P; add[R]=((LL)add[R]+add[o])%P;
     44         add[o]=0;
     45     }  
     46 }
     47 void Push_up(int o,int l,int r){
     48     if (l<r) sum[o]=(sum[L]+sum[R])%P; else sum[o]=0;
     49     sum[o]=((LL)sum[o]*mul[o]+(LL)add[o]*(r-l+1))%P;
     50 }
     51 void build(int o,int l,int r){
     52     if (l==r) add[o]=sum[o]=a[l],mul[o]=1;
     53     else{
     54         build(L,l,mid);
     55         build(R,mid+1,r);
     56         add[o]=0; mul[o]=1;
     57         Push_up(o,l,r);
     58     }
     59 }
     60 int ql,qr;
     61 void update_add(int o,int l,int r,int v){
     62     if (ql<=l && qr>=r)
     63         add[o]=((LL)add[o]+v)%P;
     64     else{
     65         if (mul[o]!=1 || add[o]) Push_down(o,l,r);
     66         if (ql<=mid) update_add(L,l,mid,v); else Push_up(L,l,mid);
     67         if (qr>mid) update_add(R,mid+1,r,v); else Push_up(R,mid+1,r);
     68     }
     69     Push_up(o,l,r);
     70 }
     71 void update_mul(int o,int l,int r,int v){
     72     if (ql<=l && qr>=r)
     73         mul[o]=((LL)mul[o]*v)%P,add[o]=(LL)add[o]*v%P;
     74     else{
     75         if (mul[o]!=1 || add[o]) Push_down(o,l,r);
     76         if (ql<=mid) update_mul(L,l,mid,v); else Push_up(L,l,mid);
     77         if (qr>mid) update_mul(R,mid+1,r,v); else Push_up(R,mid+1,r);
     78     }
     79     Push_up(o,l,r);
     80 }
     81 int sumv;
     82 void query(int o,int l,int r){
     83     if (ql<=l && qr>=r)
     84         sumv=((LL)sumv+sum[o])%P;
     85     else{
     86         if (mul[o]!=1 || add[o]) {Push_down(o,l,r); Push_up(L,l,mid); Push_up(R,mid+1,r);}
     87         if (ql<=mid) query(L,l,mid);
     88         if (qr>mid) query(R,mid+1,r);
     89     }
     90 }
     91 int ans[N],cnt=0;
     92 int main(){
     93     #ifndef ONLINE_JUDGE
     94     freopen("input.txt","r",stdin);
     95 //  freopen("output.txt","w",stdout);
     96     #endif
     97     read(n); read(P);
     98     F(i,1,n) read(a[i]);
     99 //  F(i,1,n) printf("%d ",a[i]);
    100 //  printf("
    ");
    101     build(1,1,n);
    102      
    103     read(m);
    104 //  printf("m=%d
    ",m);
    105     int c,v;
    106     F(i,1,m){
    107         read(c); read(ql); read(qr);
    108 //      printf("c=%d
    ",c);
    109         switch(c){
    110             case 1: read(v); update_mul(1,1,n,v); break;
    111             case 2: read(v); update_add(1,1,n,v); break;
    112             case 3: sumv=0; query(1,1,n); ans[cnt++]=sumv;break;
    113         }
    114     }
    115     rep(i,cnt-1) printf("%d
    ",ans[i]);
    116     printf("%d",ans[cnt-1]);
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    (转)使用BigDecimal进行精确运算
    date——sql查询
    (转)每天一个linux命令(8):cp 命令,复制文件和文件夹
    (转)每天一个linux命令(15):tail 命令
    (转)Linux 下 查看以及修改文件权限
    (转)用JUnit4进行单元测试
    (转)Spring Boot Junit单元测试
    (转)ZXing解析二维码
    (转)ZXing生成二维码和带logo的二维码,模仿微信生成二维码效果
    (转)js jquery.qrcode生成二维码 带logo 支持中文
  • 原文地址:https://www.cnblogs.com/Tunix/p/4229956.html
Copyright © 2020-2023  润新知