• BZOJ3188: [Coci 2011]Upit


    3188: [Coci 2011]Upit

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 72  Solved: 24
    [Submit][Status]

    Description

    你需要维护一个序列,支持以下4种操作。一,将区间(u,v)的数覆盖为C;二,
    将区间(u,v)的数依次加上一个以C为首项、C为公差的等差数列;三,将数C插入
    第i个位置;四,查询区间(u,v)的数的和。序列最初有n个数,一共会有Q次操
    作。保证结果在longlong范围内。 
     
     

    Input

    Output

    Sample Input

    5 5
    1 2 3 4 5
    1 5 5 0
    4 4 5
    4 5 5
    2 1 5 1
    4 1 5

    Sample Output


    4
    0
    25

    HINT

    n, Q <= 100,000. 

    Source

    题解:
    问题主要在操作2
    如果我们给l-r加上一个以x为首项,y为公差的等差数列,v[k]和sum[k]都很容易计算。
    我们发现两次的操作是可以合并的  加上以x1为首项,y1为公差,再加上x2为首项,y2为公差,相当于加上了一个以x1+x2为首项,以y1+y2为公差的等差数列,这样我们就可以打lazy了!
    然后剩下的就是注意两个lazy的下传顺序了。
    代码:
      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 500000+5
     26 
     27 #define maxm 500+100
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 
     45 using namespace std;
     46 
     47 inline ll read()
     48 
     49 {
     50 
     51     ll x=0,f=1;char ch=getchar();
     52 
     53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     54 
     55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     56 
     57     return x*f;
     58 
     59 }
     60 int n,q,rt,t1,t2,tot,fa[maxn],c[maxn][2];
     61 ll s[maxn],sum[maxn],v[maxn],tag[maxn][4];
     62 inline void pushup(int x)
     63 {
     64     int l=c[x][0],r=c[x][1];
     65     s[x]=s[l]+s[r]+1;
     66     sum[x]=sum[l]+sum[r]+v[x];
     67 }
     68 inline void rotate(int x,int &k)
     69 {
     70     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
     71     if(y!=k)c[z][c[z][1]==y]=x;else k=x;
     72     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
     73     c[y][l]=c[x][r];c[x][r]=y;
     74     pushup(y);pushup(x);
     75 }
     76 inline void splay(int x,int &k)
     77 {
     78     while(x!=k)
     79     {
     80         int y=fa[x],z=fa[y];
     81         if(y!=k)
     82         {
     83             if(c[z][0]==y^c[y][0]==x)rotate(x,k);else rotate(y,k);
     84         }
     85         rotate(x,k);
     86     }
     87 }
     88 inline void change(int x,ll z)
     89 {
     90     sum[x]=s[x]*z;v[x]=z;
     91     tag[x][0]=1;tag[x][1]=z;
     92     tag[x][2]=tag[x][3]=0;
     93 }
     94 inline void update(int x,ll y,ll z)
     95 {
     96     int l=c[x][0],r=c[x][1];
     97     v[x]+=y+s[l]*z;
     98     sum[x]+=s[x]*y+s[x]*(s[x]-1)/(ll)2*z;
     99     tag[x][2]+=y;tag[x][3]+=z;
    100 }
    101 inline void pushdown(int x)
    102 {
    103     int l=c[x][0],r=c[x][1];
    104     if(tag[x][0]){change(l,tag[x][1]);change(r,tag[x][1]);tag[x][0]=0;}
    105     if(tag[x][2]||tag[x][3])
    106     {
    107         update(l,tag[x][2],tag[x][3]);
    108         update(r,tag[x][2]+(s[l]+1)*tag[x][3],tag[x][3]);
    109         tag[x][2]=tag[x][3]=0;
    110     }
    111 }
    112 inline int find(int x,int k)
    113 {
    114     pushdown(x);
    115     int l=c[x][0],r=c[x][1];
    116     if(s[l]+1==k)return x;
    117     else if(s[l]>=k)return find(l,k);
    118     else return find(r,k-s[l]-1);
    119 }
    120 inline void split(int l,int r)
    121 {
    122     t1=find(rt,l);t2=find(rt,r);
    123     splay(t1,rt);splay(t2,c[t1][1]);
    124 }
    125 inline void build(int l,int r,int f)
    126 {
    127     if(l>r)return;
    128     int x=(l+r)>>1;
    129     fa[x]=f;c[f][x>f]=x;
    130     if(l==r){s[x]=1;sum[x]=v[x];return;}
    131     build(l,x-1,x);build(x+1,r,x);
    132     pushup(x);
    133 }
    134 
    135 int main()
    136 
    137 {
    138 
    139     freopen("input.txt","r",stdin);
    140 
    141     freopen("output.txt","w",stdout);
    142 
    143     n=read();q=read();
    144     for2(i,2,n+1)v[i]=read();tot=n+2;rt=(1+n+2)>>1;
    145     build(1,n+2,0);
    146     while(q--)
    147     {
    148         int ch=read();
    149         if(ch==3){int x=read();split(x,x+1);fa[c[t2][0]=++tot]=t2;sum[tot]=v[tot]=read();s[tot]=1;}
    150         else
    151         {
    152             int x=read(),y=read();
    153             split(x,y+2);
    154             if(ch==1)change(c[t2][0],read());
    155             else if(ch==4)printf("%lld
    ",sum[c[t2][0]]);
    156             else 
    157             {
    158                 ll z=read();update(c[t2][0],z,z);
    159             }    
    160         }
    161         pushup(t2);pushup(t1);
    162     }
    163 
    164     return 0;
    165 
    166 } 
    View Code
  • 相关阅读:
    关于全景漫游
    webgl圈中物体
    css3の极限
    reactjs弹幕视频播放
    数值积分I
    显出你的h5逼格
    奇葩のbeforeunload
    面试问题搜集及解析
    TCP拥塞控制(滑动窗口机制)
    如何使CPU占用率为50%
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4136878.html
Copyright © 2020-2023  润新知