• BZOJ 1798 (线段树||分块)的标记合并


    我原来准备做方差的。。

    结果发现不会维护两个标记。。

    就是操作变成一个 a*x+b ,每次维护a , b 即可

    加的时候a=1 ,b=v

    乘的时候a=v ,b=0

      1 #include <cstdio>
      2 const long long Maxn=100010;
      3 
      4 long long a[Maxn],n,P,l,r,c,m,type;
      5 struct Node
      6 {
      7     long long mul,add,sum,len;
      8 }tree[Maxn<<2];
      9 
     10 inline void Change(long long o,long long mul,long long add)
     11 {
     12     tree[o].mul=(tree[o].mul*mul)%P;
     13     tree[o].add=(tree[o].add*mul+add)%P;
     14     tree[o].sum=(tree[o].sum*mul+tree[o].len*add)%P;
     15 }
     16 inline void push_down(long long o)
     17 {
     18     Change(o<<1,tree[o].mul,tree[o].add);
     19     Change(o<<1|1,tree[o].mul,tree[o].add);
     20     tree[o].mul=1; tree[o].add=0;
     21 }
     22 inline void push_up(long long o)
     23 {
     24     tree[o].sum=(tree[o<<1].sum+tree[o<<1|1].sum)%P;
     25     tree[o].len=tree[o<<1].len+tree[o<<1|1].len;
     26 }
     27 void Build(long long o,long long l,long long r)
     28 {
     29     tree[o].mul=1; tree[o].add=0;
     30     if (l==r) {tree[o].sum=a[l]; tree[o].len=1; return;}
     31     long long mid=(l+r)>>1;
     32     Build(o<<1,l,mid),Build(o<<1|1,mid+1,r);
     33     push_up(o);
     34 }
     35 void Mul(long long o,long long l,long long r,long long p,long long q,long long v)
     36 {
     37     if (l==p && r==q)
     38     {
     39         Change(o,v,0);
     40         return;
     41     }
     42     push_down(o);
     43     long long mid=(l+r)>>1;
     44     if (q<=mid) Mul(o<<1,l,mid,p,q,v);
     45     if (p>=mid+1) Mul(o<<1|1,mid+1,r,p,q,v);
     46     if (p<=mid && q>=mid+1) 
     47         Mul(o<<1,l,mid,p,mid,v),Mul(o<<1|1,mid+1,r,mid+1,q,v);
     48     push_up(o);
     49 }
     50 void Add(long long o,long long l,long long r,long long p,long long q,long long v)
     51 {
     52     if (l==p && r==q)
     53     {
     54         Change(o,1,v);
     55         return;
     56     }
     57     push_down(o);
     58     long long mid=(l+r)>>1;
     59     if (q<=mid) Add(o<<1,l,mid,p,q,v);
     60     if (p>=mid+1) Add(o<<1|1,mid+1,r,p,q,v);
     61     if (p<=mid && q>=mid+1) 
     62         Add(o<<1,l,mid,p,mid,v),Add(o<<1|1,mid+1,r,mid+1,q,v);
     63     push_up(o);
     64 }
     65 long long Sum(long long o,long long l,long long r,long long p,long long q)
     66 {
     67     if (l==p && r==q) return tree[o].sum;
     68     long long mid=(l+r)>>1;
     69     push_down(o);
     70     if (q<=mid) return Sum(o<<1,l,mid,p,q);
     71     if (p>=mid+1) return Sum(o<<1|1,mid+1,r,p,q);
     72     if (p<=mid && q>=mid+1) 
     73         return (Sum(o<<1,l,mid,p,mid)+Sum(o<<1|1,mid+1,r,mid+1,q))%P;
     74 }
     75 int main()
     76 {
     77     // freopen("c.in","r",stdin);
     78     scanf("%lld%lld",&n,&P);
     79     for (long long i=1;i<=n;i++) scanf("%lld",&a[i]);
     80     Build(1,1,n);
     81     scanf("%lld",&m);
     82     for (long long i=1;i<=m;i++)
     83     {
     84         scanf("%lld",&type);
     85         if (type==1) 
     86         {
     87             scanf("%lld%lld%lld",&l,&r,&c);
     88             Mul(1,1,n,l,r,c);
     89         }
     90         if (type==2) 
     91         {
     92             scanf("%lld%lld%lld",&l,&r,&c);
     93             Add(1,1,n,l,r,c);
     94         }
     95         if (type==3) 
     96         {
     97             scanf("%lld%lld",&l,&r);
     98             printf("%lld
    ",Sum(1,1,n,l,r));
     99         }
    100     }
    101     return 0;
    102 }
    线段树

     UPD:2016.6.14

    突然发现好久没有写过分块了,想到这道可以分块,push_up写成push_down了..

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstring>
      4 #include <iostream>
      5 #define LL long long
      6 using namespace std;
      7 const LL Maxn=600010;
      8 const LL Inf=0x3f3f3f3f;
      9 LL a[Maxn],n,P,l,r,c,m,type,Block[Maxn];
     10 struct Node
     11 {
     12     LL mul,add,len,sum;
     13 }tree[Maxn];
     14  
     15 inline void Change(LL o,LL mul,LL add)
     16 {
     17     tree[o].mul=(tree[o].mul*mul)%P;
     18     tree[o].add=(tree[o].add*mul+add)%P;
     19     tree[o].sum=(tree[o].sum*mul+tree[o].len*add)%P;
     20 }
     21 inline void push_down(LL o)
     22 {
     23     for (;Block[o]==Block[o-1];o--);
     24     for (LL i=o;Block[o]==Block[i];i++) a[i]=(a[i]*tree[Block[i]].mul+tree[Block[i]].add)%P;
     25     tree[Block[o]].mul=1,tree[Block[o]].add=0;
     26 }
     27 
     28 inline void push_up(LL o)
     29 {
     30     tree[Block[o]].sum=0;
     31     for (;Block[o]==Block[o-1];o--);
     32     for (LL i=o;Block[o]==Block[i];i++) tree[Block[o]].sum=(tree[Block[o]].sum+a[i])%P;
     33 }
     34 void Mul(LL p,LL q,LL v)
     35 {
     36     if (Block[p]==Block[q])
     37     {
     38         push_down(p);
     39         for (LL i=p;i<=q;i++) a[i]=(a[i]*v)%P; 
     40         push_up(p);
     41         return;
     42     }
     43     for (LL i=Block[p]+1;i<Block[q];i++) Change(i,v,0);
     44     push_down(p),push_down(q);
     45     for (LL i=p;Block[i]==Block[p];i++) a[i]=(a[i]*v)%P;
     46     for (LL i=q;Block[i]==Block[q];i--) a[i]=(a[i]*v)%P;
     47     push_up(p),push_up(q);
     48 }
     49 
     50 void Add(LL p,LL q,LL v)
     51 {
     52     if (Block[p]==Block[q])
     53     {
     54         push_down(p);
     55         for (LL i=p;i<=q;i++) a[i]=(a[i]+v)%P; 
     56         push_up(p);
     57         return;
     58     }
     59     for (LL i=Block[p]+1;i<Block[q];i++) Change(i,1,v);
     60     push_down(p),push_down(q);
     61     for (LL i=p;Block[i]==Block[p];i++) a[i]=(a[i]+v)%P;
     62     for (LL i=q;Block[i]==Block[q];i--) a[i]=(a[i]+v)%P;
     63     push_up(p),push_up(q);
     64 }
     65 LL Sum(LL p,LL q)
     66 {
     67     LL ret=0;
     68     if (Block[p]==Block[q]) 
     69     {
     70         push_down(p);
     71         for (LL i=p;i<=q;i++) ret=(ret+a[i])%P;
     72         return ret;
     73     }
     74     for (LL i=Block[p]+1;i<Block[q];i++) ret=(ret+tree[i].sum)%P;
     75     push_down(p),push_down(q);
     76     for (LL i=p;Block[i]==Block[p];i++) ret=(ret+a[i])%P;
     77     for (LL i=q;Block[i]==Block[q];i--) ret=(ret+a[i])%P;
     78     return ret;
     79 }
     80 int main()
     81 {
     82     scanf("%lld%lld",&n,&P);
     83     for (LL i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]%=P;
     84     LL pos=(LL)sqrt(n);
     85     for (LL i=1;i<=n;i++) Block[i]=(i-1)/pos+1;
     86     memset(tree,0,sizeof(tree));
     87     for (LL i=1;i<=n;i++) tree[Block[i]].len++;
     88     for (LL i=1;i<=n;i++) tree[Block[i]].mul=1;
     89     for (LL i=1;i<=n;i++) tree[Block[i]].sum=(tree[Block[i]].sum+a[i])%P;
     90 
     91     scanf("%lld",&m);
     92     for (LL i=1;i<=m;i++)
     93     {
     94         scanf("%lld",&type);
     95         if (type==1) 
     96         {
     97             scanf("%lld%lld%lld",&l,&r,&c);
     98             Mul(l,r,c);
     99         }
    100         if (type==2) 
    101         {
    102             scanf("%lld%lld%lld",&l,&r,&c);
    103             Add(l,r,c);
    104         }
    105         if (type==3) 
    106         {
    107             scanf("%lld%lld",&l,&r);
    108             printf("%lld
    ",Sum(l,r));
    109         }
    110     }
    111     return 0;
    112 }
    分块
  • 相关阅读:
    Java课程设计-计算器 丁树乐(201521123024)
    201521123024 《Java程序设计》第13周学习总结
    201521123024 《java程序设计》 第12周学习总结
    201521123024 《Java程序设计》第11周学习总结
    201521123024 java 第十周学习总结
    软工个人作业5-软件工程总结
    软工个人作业3案例分析
    结对编程练习
    软件工程网络15个人阅读2
    软工网络15个人阅读作业1
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5474101.html
Copyright © 2020-2023  润新知