个人感觉:

  • 代码长;
  • 函数多;
  • (很套路);
  • (很强的Splay,无愧于“区间王”)

NOI2005维修数列

  • 一个可以当模板学习的题,包含了众多操作(函数):
  • 区间插入,删除,更新,翻转,询问信息以及”回收空间”(名字很刚)等。
  • update()pushdown() rotate() splay() build() find() split() insert() rec() erase() query() rever() modify()还有main()
  • 建议初学Splay者打一打;
  • 代码:
  •   1 #include<queue>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<iostream>
      7 #include<algorithm>
      8 #define inf 1000000000
      9 #define N 1000005
     10 using namespace std;
     11 int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 int n,m,rt,cnt,k,len,val; char ch[10];
     19 int a[N],id[N],fa[N],c[N][2];
     20 int sum[N],siz[N],v[N],mx[N],lx[N],rx[N];
     21 bool tag[N],rev[N];
     22 queue<int> q;
     23 void update(int x)                                            
     24 {
     25     int l=c[x][0],r=c[x][1];
     26     sum[x]=sum[l]+sum[r]+v[x];
     27     siz[x]=siz[l]+siz[r]+1;
     28     mx[x]=max(mx[l],mx[r]);
     29     mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);
     30     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
     31     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
     32 }
     33 void pushdown(int x)                                          
     34 {
     35     int l=c[x][0],r=c[x][1];
     36     if(tag[x])
     37     {
     38         rev[x]=tag[x]=0;                          
     39         if(l) tag[l]=1,v[l]=v[x],sum[l]=v[l]*siz[l];
     40         if(r) tag[r]=1,v[r]=v[x],sum[r]=v[r]*siz[r];
     41         if(v[x]>=0)
     42         {
     43             if(l) lx[l]=rx[l]=mx[l]=sum[l];
     44             if(r) lx[r]=rx[r]=mx[r]=sum[r];
     45         }
     46         else 
     47         {
     48             if(l)lx[l]=rx[l]=0,mx[l]=v[x];
     49             if(r)lx[r]=rx[r]=0,mx[r]=v[x];
     50         }
     51     }
     52     if(rev[x])
     53     {
     54         rev[x]^=1;rev[l]^=1;rev[r]^=1;        
     55          swap(lx[l],rx[l]);swap(lx[r],rx[r]); 
     56         swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]);
     57     }
     58 }
     59 void rotate(int x,int &k)//Ðýת£¨µ¥£© 
     60 {
     61     int y=fa[x],z=fa[y];
     62     int l=(x!=c[y][0]),r=l^1;
     63     if(y==k) k=x;
     64     else c[z][y!=c[z][0]]=x;
     65     fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
     66     c[y][l]=c[x][r]; c[x][r]=y;
     67     update(y); update(x);
     68 }
     69 void splay(int x,int &k) 
     70 {
     71     int y,z;
     72     while(x!=k)
     73     {
     74         y=fa[x],z=fa[y];
     75         if(y!=k)
     76         {
     77             if(c[y][0]==x^c[z][0]==y) rotate(x,k);
     78             else rotate(y,k);
     79         }
     80         rotate(x,k);
     81     }
     82 }
     83 void build(int l,int r,int f)
     84 {
     85     if(l>r) return;
     86     int mid=l+r>>1,now=id[mid],last=id[f];
     87     if(l==r)
     88     {
     89         sum[now]=a[l];
     90         siz[now]=1;
     91         tag[now]=rev[now]=0;
     92         if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l];
     93         else lx[now]=rx[now]=0,mx[now]=a[l];
     94     }
     95     build(l,mid-1,mid);build(mid+1,r,mid);
     96     v[now]=a[mid];
     97     fa[now]=last;
     98     c[last][mid>=f]=now;
     99     update(now);
    100 }
    101 int find(int k,int x) 
    102 {
    103     pushdown(k);
    104     if(siz[c[k][0]]+1==x) return k; 
    105     if(siz[c[k][0]]>=x) return find(c[k][0],x);
    106     else return find(c[k][1],x-siz[c[k][0]]-1);
    107 }
    108 int split(int k,int len)
    109 {                                                                                                    
    110     int x=find(rt,k),y=find(rt,k+len+1);
    111     splay(x,rt);splay(y,c[x][1]);
    112     return c[y][0];
    113 }
    114 void insert(int k,int len)
    115 {
    116     for(int i=1;i<=len;i++)
    117     if(!q.empty()) id[i]=q.front(),q.pop();
    118     else id[i]=++cnt;
    119     for(int i=1;i<=len;i++) a[i]=read();
    120     build(1,len,0);
    121     int x=id[1+len>>1];
    122     int z=find(rt,k+1),y=find(rt,k+2);//µÚһλΪ-inf 
    123     splay(z,rt); splay(y,c[z][1]);
    124     fa[x]=y; c[y][0]=x;
    125     update(y);update(fa[y]);
    126 }
    127 void rec(int x) 
    128 {                                                            
    129     if(!x) return;
    130     int l=c[x][0],r=c[x][1];
    131     rec(l); rec(r);
    132     q.push(x);
    133     fa[x]=c[x][0]=c[x][1]=0;
    134     tag[x]=rev[x]=0;
    135 }
    136 void erase(int k,int len)
    137 {
    138     int x=split(k,len),y=fa[x];
    139     rec(x); c[y][0]=0;
    140     update(y);update(fa[y]);
    141 }
    142 void query(int k,int len)
    143 {
    144     int x=split(k,len);
    145     printf("%d\n",sum[x]);
    146 }
    147 void rever(int k,int len)//Çø¼ä·­×ª 
    148 {
    149     int x=split(k,len),y=fa[x];
    150     if(!tag[x])
    151     {
    152         rev[x]^=1;                        
    153         swap(lx[x],rx[x]);
    154         swap(c[x][0],c[x][1]);
    155         update(y);update(fa[y]);
    156     }
    157 }
    158 void modify(int k,int len,int val)
    159 {
    160     int x=split(k,len),y=fa[x];
    161     tag[x]=1; v[x]=val;
    162     sum[x]=v[x]*siz[x];
    163     if(v[x]>=0) lx[x]=rx[x]=mx[x]=sum[x];
    164     else lx[x]=rx[x]=0,mx[x]=v[x];
    165     update(y);update(fa[y]);
    166 }
    167 int main()
    168 {
    169     n=read();m=read();
    170     mx[0]=a[1]=a[n+2]=-inf; id[1]=1; id[n+2]=n+2;
    171     for(int i=2;i<=n+1;i++) a[i]=read(),id[i]=i;
    172     build(1,n+2,0);
    173     rt=n+3>>1; cnt=n+2;
    174     while(m-->0)
    175     {
    176         scanf("%s",ch);
    177         if(ch[0]!='M'||ch[2]!='X') k=read(),len=read();
    178         if(ch[0]=='I') insert(k,len);
    179         if(ch[0]=='D') erase(k,len);
    180         if(ch[0]=='R') rever(k,len);
    181         if(ch[0]=='G') query(k,len);
    182         if(ch[0]=='M')
    183         {
    184             if(ch[2]=='X')printf("%d\n",mx[rt]);
    185             else val=read(),modify(k,len,val);
    186         }
    187     }
    188     return 0;
    189 }
    I'm here!

相关文章:

  • 2022-12-23
  • 2021-07-24
  • 2021-10-27
猜你喜欢
  • 2022-12-23
  • 2021-12-02
  • 2021-05-27
  • 2022-12-23
  • 2022-12-23
  • 2021-10-05
  • 2021-11-27
相关资源
相似解决方案