zoukankan      html  css  js  c++  java
  • NOI2005维修数列

    学习hzwer的代码。

    http://hzwer.com/2841.html

    这是一道经典的splay模板题

    入门建议阅读《伸展树的基本操作与应用》,以及手画练习

    以下模板是结合前人经验,经多次修改后的结果

    c分别是结点左右儿子,fa是结点父亲

    size是子树大小,sum是子树权值和,v是结点权值,mx是当前子树的最大子串和

    lx是一个子树以最左端为起点向右延伸的最大子串和,rx类似

    tag是结点的修改标记,修改值为v,rev是翻转标记

    按照位置建树。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int inf=1e9,N=1e6+5;
      4 int n,m,rt,cnt;
      5 int a[N],id[N],fa[N],c[N][2];
      6 int sum[N],size[N],v[N],mx[N],lx[N],rx[N];
      7 bool tag[N],rev[N];
      8 queue<int>q;
      9 void update(int x)
     10 {
     11     int l=c[x][0],r=c[x][1];
     12     sum[x]=sum[l]+sum[r]+v[x];
     13     size[x]=size[l]+size[r]+1;
     14     mx[x]=max(mx[l],mx[r]);
     15     mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);
     16     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
     17     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
     18 }
     19 void pushdown(int x)
     20 {
     21     int l=c[x][0],r=c[x][1];
     22     if(tag[x])
     23     {
     24         rev[x]=tag[x]=0;
     25         if(l)tag[l]=1,v[l]=v[x],sum[l]=v[x]*size[l];
     26         if(r)tag[r]=1,v[r]=v[x],sum[r]=v[x]*size[r];
     27         if(v[x]>=0)
     28         {
     29             if(l)lx[l]=rx[l]=mx[l]=sum[l];
     30             if(r)lx[r]=rx[r]=mx[r]=sum[r];
     31         }
     32         else
     33         {
     34             if(l)lx[l]=rx[l]=0,mx[l]=v[x];
     35             if(r)lx[r]=rx[r]=0,mx[r]=v[x];
     36         }
     37     }
     38     if(rev[x])
     39     {
     40         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     41         swap(lx[l],rx[l]);swap(lx[r],rx[r]);
     42         swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]);
     43     }
     44 }
     45 void rotate(int x,int &k)
     46 {
     47     int y=fa[x],z=fa[y],l,r;
     48     l=(c[y][1]==x);r=l^1;
     49     if(y==k)k=x;
     50     else c[z][c[z][1]==y]=x;
     51     fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
     52     c[y][l]=c[x][r];c[x][r]=y;
     53     update(y);update(x);
     54 }
     55 void splay(int x,int &k)
     56 {
     57     while(x!=k)
     58     {
     59         int y=fa[x],z=fa[y];
     60         if(y!=k)
     61         {
     62             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
     63             else rotate(y,k);
     64         }
     65         rotate(x,k);
     66     }
     67 }
     68 int find(int x,int rk)
     69 {
     70     pushdown(x);
     71     int l=c[x][0],r=c[x][1];
     72     if(size[l]+1==rk)return x;
     73     if(size[l]>=rk)return find(l,rk);
     74     return find(r,rk-size[l]-1);
     75 }
     76 void rec(int x)
     77 {
     78     if(!x)return;
     79     int l=c[x][0],r=c[x][1];
     80     rec(l);rec(r);q.push(x);
     81     fa[x]=c[x][0]=c[x][1]=0;
     82     tag[x]=rev[x]=0;
     83 }
     84 int split(int k,int tot)
     85 {
     86     int x=find(rt,k),y=find(rt,k+tot+1);
     87     splay(x,rt);splay(y,c[x][1]);
     88     return c[y][0];
     89 }
     90 void query(int k,int tot)
     91 {
     92     int x=split(k,tot);
     93     printf("%d
    ",sum[x]);
     94 }
     95 void modify(int k,int tot,int val)
     96 {
     97     int x=split(k,tot),y=fa[x];
     98     v[x]=val;tag[x]=1;sum[x]=size[x]*val;
     99     if(val>=0)lx[x]=rx[x]=mx[x]=sum[x];
    100     else lx[x]=rx[x]=0,mx[x]=val;
    101     update(y);update(fa[y]);
    102 }
    103 void rever(int k,int tot)
    104 {
    105     int x=split(k,tot),y=fa[x];
    106     if(!tag[x])
    107     {
    108         rev[x]^=1;
    109         swap(c[x][0],c[x][1]);
    110         swap(lx[x],rx[x]);
    111         update(y);update(fa[y]);
    112     }
    113 }
    114 void erase(int k,int tot)
    115 {
    116     int x=split(k,tot),y=fa[x];
    117     rec(x);c[y][0]=0;
    118     update(y);update(fa[y]);
    119 }
    120 void build(int l,int r,int f)
    121 {
    122     if(l>r)return;
    123     int mid=(l+r)>>1,now=id[mid],last=id[f];
    124     if(l==r)
    125     {
    126         sum[now]=a[l];size[now]=1;
    127         tag[now]=rev[now]=0;
    128         if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l];
    129         else lx[now]=rx[now]=0,mx[now]=a[l];
    130     }
    131     else build(l,mid-1,mid),build(mid+1,r,mid);
    132     v[now]=a[mid];fa[now]=last;update(now);
    133     c[last][mid>=f]=now;
    134 }
    135 void insert(int k,int tot)
    136 {
    137     for(int i=1;i<=tot;++i)scanf("%d",&a[i]);
    138     for(int i=1;i<=tot;++i)
    139     {
    140         if(!q.empty())id[i]=q.front(),q.pop();
    141         else id[i]=++cnt;
    142     }
    143     build(1,tot,0);int z=id[(1+tot)>>1];
    144     int x=find(rt,k+1),y=find(rt,k+2);
    145     splay(x,rt);splay(y,c[x][1]);
    146     fa[z]=y;c[y][0]=z;
    147     update(y);update(x);
    148 }
    149 int main()
    150 {
    151     scanf("%d%d",&n,&m);
    152     mx[0]=a[1]=a[n+2]=-inf;
    153     for(int i=1;i<=n;++i)scanf("%d",&a[i+1]);
    154     for(int i=1;i<=n+2;++i)id[i]=++cnt;
    155     build(1,n+2,0);
    156     rt=(n+3)>>1;
    157     int k,tot,val;
    158     char ch[10];
    159     while(m--)
    160     {
    161         scanf("%s",ch);
    162         if(ch[0]!='M'||ch[2]!='X')scanf("%d%d",&k,&tot);
    163         if(ch[0]=='I')insert(k,tot);
    164         if(ch[0]=='D')erase(k,tot);
    165         if(ch[0]=='M')
    166         {
    167             if(ch[2]=='X')printf("%d
    ",mx[rt]);
    168             else scanf("%d",&val),modify(k,tot,val);
    169         }
    170         if(ch[0]=='R')rever(k,tot);
    171         if(ch[0]=='G')query(k,tot);
    172     }
    173     return 0;
    174 }
  • 相关阅读:
    git速度慢解决方式
    idea破解
    高并发redis分布式锁
    一个简单的struts2项目
    一个简单的java项目使用hibernate连接mysql数据库
    hibernate连接数据库中文乱码
    删除文件时出现找不到该项目 请确认该项目位置
    redis错误解决
    pyQT4和pyQT5的主要模块介绍
    python之type函数
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8280633.html
Copyright © 2011-2022 走看看