bzoj1500: [NOI2005]维修数列

2 篇文章 0 订阅

真是一道很恶心的题(还是说变态??)

反正splay操作很多,有点难打什么的。。。

不想说什么,题解到处有。。贴个代码纪念一下

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#define inf 1000000000
#define me(a,x) memset(a,x,sizeof a)
#define N 600010
using namespace std;
struct node
{
    int d,c,f,son[2];
}t[N];
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int rt,id[N],mx[N],lx[N],rx[N],v[N],len,a[N];
bool tag[N],rev[N];
queue
       
       
         q; void update(int x) { int lc=t[x].son[0],rc=t[x].son[1]; lx[x]=max(lx[lc],t[lc].d+v[x]+lx[rc]); rx[x]=max(rx[rc],t[rc].d+v[x]+rx[lc]); t[x].c=t[lc].c+t[rc].c+1; t[x].d=t[lc].d+t[rc].d+v[x]; mx[x]=max(mx[lc],max(mx[rc],lx[rc]+v[x]+rx[lc])); } void pushdown(int x) { int l=t[x].son[0],r=t[x].son[1]; if(tag[x]) { rev[x]=tag[x]=0; if(l)tag[l]=1,v[l]=v[x],t[l].d=v[x]*t[l].c; if(r)tag[r]=1,v[r]=v[x],t[r].d=v[x]*t[r].c; if(v[x]>=0) { if(l)lx[l]=rx[l]=mx[l]=t[l].d; if(r)lx[r]=rx[r]=mx[r]=t[r].d; } else { if(l)lx[l]=rx[l]=0,mx[l]=v[x]; if(r)lx[r]=rx[r]=0,mx[r]=v[x]; } } if(rev[x]) { rev[x]^=1;rev[l]^=1;rev[r]^=1; swap(lx[l],rx[l]); swap(lx[r],rx[r]); swap(t[l].son[0],t[l].son[1]); swap(t[r].son[0],t[r].son[1]); } } void rotate(int x,int &k) { int y=t[x].f,z=t[y].f; if(y==k)k=x; else t[z].son[t[z].son[1]==y]=x; int w=(x==t[y].son[1]),g=t[x].son[!w]; t[g].f=y,t[y].son[w]=g; t[y].f=x,t[x].son[!w]=y; t[x].f=z; update(y); update(x); } void splay(int x,int &k) { while(x!=k) { int y=t[x].f,z=t[y].f; int w=(x==t[y].son[1]), u=(y==t[z].son[1]); if(y!=k) { if(w==u)rotate(y,k); else rotate(x,k); } rotate(x,k); } } int find(int x,int rk) { pushdown(x); int l=t[x].son[0],r=t[x].son[1]; if(t[l].c+1==rk)return x; if(t[l].c>=rk)return find(l,rk); return find(r,rk-t[l].c-1); } int split(int p,int k) { int x=find(rt,p),y=find(rt,p+k+1); splay(x,rt),splay(y,t[x].son[1]); return t[y].son[0]; } void rec(int x) { if(!x)return; int l=t[x].son[0],r=t[x].son[1]; rec(l),rec(r); q.push(x); t[x].f=t[x].son[0]=t[x].son[1]=tag[x]=rev[x]=0; } void del(int p,int k) { int x=split(p,k),y=t[x].f; rec(x); t[y].son[0]=0; update(y),update(t[y].f); } void make_same(int p,int k,int val) { int x=split(p,k),y=t[x].f; v[x]=val,tag[x]=1,t[x].d=t[x].c*val; if(val>=0)lx[x]=rx[x]=mx[x]=t[x].d; else lx[x]=rx[x]=0,mx[x]=val; update(y),update(t[y].f); } void rever(int p,int k) { int x=split(p,k),y=t[x].f; if(tag[x])return; rev[x]^=1; swap(t[x].son[0],t[x].son[1]); swap(lx[x],rx[x]); update(y),update(t[y].f); } void bulid(int &now,int l,int r,int f) { if(l>r){now=0; return;} int mid=(l+r)>>1; now=id[mid]; t[now].f=f; if(l==r) { t[now].d=a[l],t[now].c=1; if(a[l]>0) lx[now]=rx[now]=mx[now]=a[l]; else lx[now]=rx[now]=0,mx[now]=a[l]; } else bulid(t[now].son[0],l,mid-1,now),bulid(t[now].son[1],mid+1,r,now); v[now]=a[mid]; update(now); } void query(int p,int k) { int x=split(p,k); printf("%d\n",t[x].d); } void ins(int p,int k) { int i; for(i=1;i<=k;i++)a[i]=read(); for(i=1;i<=k;i++) if(!q.empty())id[i]=q.front(),q.pop(); else id[i]=++len; int x=find(rt,p+1) , y=find(rt,p+2); splay(x,rt) , splay(y,t[x].son[1]); bulid(t[y].son[0],1,k,y); update(y); update(x); } char s[20]; int main() { int n,m,i,x,y,k; n=read(),m=read(); a[1]=a[n+2]=mx[0]=-inf; for(i=1;i<=n;i++)a[i+1]=read(); for(i=1;i<=n+2;i++)id[i]=i; bulid(rt,1,n+2,0); len=n+2; while(m--) { scanf("%s",s); if(s[2]!='X')x=read(),k=read(); if(s[0]=='I')ins(x,k); if(s[0]=='D')del(x,k); if(s[0]=='M') { if(s[2]=='X')printf("%d\n",mx[rt]); else {y=read(); make_same(x,k,y);} } if(s[0]=='R')rever(x,k); if(s[0]=='G')query(x,k); } return 0; } 
       
      
      
     
     
    
    
   
   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值