zoukankan      html  css  js  c++  java
  • bzoj 1798 [Ahoi2009]Seq 维护序列seq ——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1798

    先乘后加,就可给加法标记乘上乘法标记。

    注意可能有 *0 的操作,所以 pshd 时不是 cg[ cr ]>1 而是 cg[ cr ]!=1 。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define ls Ls[cr]
    #define rs Rs[cr]
    using namespace std;
    const int N=1e5+5,M=N<<1;
    int n,m,mod,a[N],Ls[M],Rs[M],cg[M],jg[M],sm[M],tot;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int g[20];
    void wrt(int x)
    {
      if(x<0)putchar('-'),x=-x;
      if(!x){puts("0");return;}
      int t=0;while(x)g[++t]=x%10,x/=10;
      while(t)putchar(g[t]+'0'),t--;puts("");
    }
    void upd(int &x){x>=mod?x-=mod:0;}
    void pshp(int cr){sm[cr]=sm[ls]+sm[rs];upd(sm[cr]);}
    void build(int l,int r,int cr)
    {
      cg[cr]=1;
      if(l==r){sm[cr]=a[l]%mod;return;}
      int mid=l+r>>1;
      ls=++tot; build(l,mid,ls);
      rs=++tot; build(mid+1,r,rs);
      pshp(cr);
    }
    void pshd(int cr,int l,int mid,int r)
    {
      if(cg[cr]!=1)
        {
          int w=cg[cr]; cg[cr]=1;
          cg[ls]=(ll)cg[ls]*w%mod; cg[rs]=(ll)cg[rs]*w%mod;
          jg[ls]=(ll)jg[ls]*w%mod; jg[rs]=(ll)jg[rs]*w%mod;
          sm[ls]=(ll)sm[ls]*w%mod; sm[rs]=(ll)sm[rs]*w%mod;
        }
      if(jg[cr])
        {
          int w=jg[cr]; jg[cr]=0;
          jg[ls]+=w;upd(jg[ls]); jg[rs]+=w;upd(jg[rs]);
          sm[ls]=(sm[ls]+(ll)(mid-l+1)*w)%mod; sm[rs]=(sm[rs]+(ll)(r-mid)*w)%mod;
        }
    }
    void mdfy(int l,int r,int cr,int L,int R,int k,bool fx)
    {
      if(l>=L&&r<=R)
        {
          if(!fx)
        cg[cr]=(ll)cg[cr]*k%mod, sm[cr]=(ll)sm[cr]*k%mod, jg[cr]=(ll)jg[cr]*k%mod;
          else
        jg[cr]+=k,upd(jg[cr]),sm[cr]=(sm[cr]+(ll)(r-l+1)*k)%mod;
          return;
        }
      int mid=l+r>>1; pshd(cr,l,mid,r);
      if(L<=mid)mdfy(l,mid,ls,L,R,k,fx);
      if(mid<R)mdfy(mid+1,r,rs,L,R,k,fx);
      pshp(cr);
    }
    int query(int l,int r,int cr,int L,int R)
    {
      if(l>=L&&r<=R)return sm[cr];
      int mid=l+r>>1,ret=0; pshd(cr,l,mid,r);
      if(L<=mid)ret=query(l,mid,ls,L,R);
      if(mid<R)ret+=query(mid+1,r,rs,L,R),upd(ret);
      return ret;
    }
    int main()
    {
      n=rdn(); mod=rdn();
      for(int i=1;i<=n;i++)a[i]=rdn();
      tot=1; build(1,n,1);
      m=rdn();
      for(int i=1,op,l,r,k;i<=m;i++)
        {
          op=rdn();l=rdn();r=rdn();
          if(op==1)
        {
          k=rdn()%mod;mdfy(1,n,1,l,r,k,0);
        }
          if(op==2)
        {
          k=rdn()%mod;mdfy(1,n,1,l,r,k,1);
        }
          if(op==3)
        wrt(query(1,n,1,l,r));
        }
      return 0;
    }
  • 相关阅读:
    二级菜单
    eclipse高版本中EasyExplore的替换插件OpenExplore
    Python学习一
    原型编程的基本规则
    【CF671D】 Roads in Yusland(对偶问题,左偏树)
    【洛谷4542】 [ZJOI2011]营救皮卡丘(最小费用最大流)
    【洛谷4313】 文理分科(最小割)
    【洛谷4001】 [ICPC-Beijing 2006]狼抓兔子(最小割)
    【洛谷2057】 [SHOI2007]善意的投票(最小割)
    【洛谷2053】 [SCOI2007]修车(费用流)
  • 原文地址:https://www.cnblogs.com/Narh/p/9887199.html
Copyright © 2011-2022 走看看