zoukankan      html  css  js  c++  java
  • bzoj1798: [Ahoi2009]Seq 维护序列seq(线段树)

    1798: [Ahoi2009]Seq 维护序列seq

    题目:传送门


    题解:

       好题!毒瘤恶心题!

       有打过线段树lazy的经验之后其实并不难,也就加niang个lazy标记死磕代码咯

       吐槽:update先加后乘WA...反过来...A了


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 typedef long long LL;
      8 struct trnode
      9 {
     10     int l,r,lc,rc;LL sum;
     11     LL lzj,lzc;//lazy 有标记则表示自己已经改了但是管理的区间没改 
     12 }tr[410000];int trlen,n,m,mod;
     13 int a[410000];
     14 void bt(int l,int r)
     15 {
     16     int now=++trlen;
     17     tr[now].l=l;tr[now].r=r;
     18     if(l==r)
     19     {
     20         tr[now].lc=tr[now].rc=0;
     21         tr[now].sum=a[l];tr[now].lzj=0;tr[now].lzc=1;
     22     }
     23     else
     24     {
     25         int mid=(l+r)/2;
     26         tr[now].lc=trlen+1;bt(l,mid);
     27         tr[now].rc=trlen+1;bt(mid+1,r);
     28         tr[now].sum=(tr[tr[now].lc].sum+tr[tr[now].rc].sum)%mod;
     29         tr[now].lzj=0;tr[now].lzc=1;
     30     }
     31 }
     32 void update(int now)
     33 {
     34     int lc=tr[now].lc,rc=tr[now].rc;
     35     if(tr[now].lzc!=1)
     36     {
     37         tr[lc].sum=(tr[lc].sum*tr[now].lzc)%mod;
     38         tr[lc].lzj=(tr[lc].lzj*tr[now].lzc)%mod;
     39         tr[lc].lzc=(tr[lc].lzc*tr[now].lzc)%mod;
     40         tr[rc].sum=(tr[rc].sum*tr[now].lzc)%mod;
     41         tr[rc].lzj=(tr[rc].lzj*tr[now].lzc)%mod;
     42         tr[rc].lzc=(tr[rc].lzc*tr[now].lzc)%mod;
     43         tr[now].lzc=1;
     44     }
     45     if(tr[now].lzj!=0)
     46     {
     47         int cnt;
     48         cnt=tr[lc].r-tr[lc].l+1;
     49         tr[lc].sum=(tr[lc].sum+cnt*tr[now].lzj)%mod;
     50         tr[lc].lzj=(tr[lc].lzj+tr[now].lzj)%mod;
     51         cnt=tr[rc].r-tr[rc].l+1;
     52         tr[rc].sum=(tr[rc].sum+cnt*tr[now].lzj)%mod;
     53         tr[rc].lzj=(tr[rc].lzj+tr[now].lzj)%mod;
     54         tr[now].lzj=0;
     55     }
     56 }
     57 void add(int now,int l,int r,LL x)
     58 {
     59     if(tr[now].l==l && tr[now].r==r)
     60     {
     61         update(now);
     62         int cnt=r-l+1;
     63         tr[now].sum=(tr[now].sum+cnt*x)%mod;
     64         tr[now].lzj=(tr[now].lzj+x)%mod;
     65         return ;
     66     }
     67     update(now);
     68     int mid=(tr[now].l+tr[now].r)/2,lc=tr[now].lc,rc=tr[now].rc;
     69     if(r<=mid)add(lc,l,r,x);
     70     else if(mid+1<=l)add(rc,l,r,x);
     71     else add(lc,l,mid,x),add(rc,mid+1,r,x);
     72     tr[now].sum=(tr[lc].sum+tr[rc].sum)%mod;
     73 }
     74 void multi(int now,int l,int r,LL x)
     75 {
     76     if(tr[now].l==l && tr[now].r==r)
     77     {
     78         update(now);
     79         tr[now].sum=(tr[now].sum*x)%mod;
     80         tr[now].lzj=(tr[now].lzj*x)%mod;
     81         tr[now].lzc=(tr[now].lzc*x)%mod;
     82         return ;
     83     }
     84     update(now);
     85     int mid=(tr[now].l+tr[now].r)/2,lc=tr[now].lc,rc=tr[now].rc;
     86     if(r<=mid)multi(lc,l,r,x);
     87     else if(mid+1<=l)multi(rc,l,r,x);
     88     else multi(lc,l,mid,x),multi(rc,mid+1,r,x);
     89     tr[now].sum=(tr[lc].sum+tr[rc].sum)%mod;
     90 }
     91 LL getsum(int now,int l,int r)
     92 {
     93     if(tr[now].l==l && tr[now].r==r)return tr[now].sum;
     94     update(now);
     95     int mid=(tr[now].l+tr[now].r)/2,lc=tr[now].lc,rc=tr[now].rc;
     96     if(r<=mid)return getsum(lc,l,r);
     97     else if(mid+1<=l)return getsum(rc,l,r);
     98     else return (getsum(lc,l,mid)+getsum(rc,mid+1,r))%mod;
     99 }
    100 int main()
    101 {
    102     scanf("%d%lld",&n,&mod);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    103     trlen=0;bt(1,n);
    104     scanf("%d",&m);
    105     for(int i=1;i<=m;i++)
    106     {
    107         LL x;int Q,l,r;
    108         scanf("%d",&Q);
    109         if(Q==1)
    110         {
    111             scanf("%d%d%lld",&l,&r,&x);
    112             multi(1,l,r,x%mod);
    113         }
    114         if(Q==2)
    115         {
    116             scanf("%d%d%lld",&l,&r,&x);
    117             add(1,l,r,x%mod);
    118         }
    119         if(Q==3)
    120         {
    121             scanf("%d%d",&l,&r);
    122             printf("%lld
    ",getsum(1,l,r));
    123         }
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    FTP文件乱码和传输模式解释
    win7(x64)+VS2012+cocos2d-x环境的配置以及试运行
    XCode详解及iOSApp上传
    WP8教程
    Windows Phone 8 开发环境搭建
    Wp8开发环境搭建总结
    跟随玩家
    JniHelper 含安卓推送
    软硬结合第二篇——酷我音乐盒的逆天玩法
    IOS ITunesConnect 修改开发商名称
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8537390.html
Copyright © 2011-2022 走看看