bzoj1588
Posted 宣毅鸣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1588相关的知识,希望对你有一定的参考价值。
题解:
我们发现,今天的波动=min(x-pre,nxt-x)
所以可以维护一颗平衡树
模板前驱后继即可
代码:
#include<bits/stdc++.h> using namespace std; const int N=1000005; int in[2*N],pre[N],data[N],tot,size[N],c[N][2],root,n,x; void rot(int x) { int y=pre[x],k=(x==c[y][0]); size[k]=size[c[y][k]]+size[c[x][k]]+1; size[x]=size[c[x][!k]]+size[y]+1; c[y][!k]=c[x][k]; pre[c[y][!k]]=y; pre[x]=pre[y]; if (pre[y])c[pre[y]][c[pre[y]][1]==y]=x; c[x][k]=y;pre[y]=x; } void splay(int x,int g) { for (int y=pre[x];y!=g;rot(x),y=pre[x]) if (pre[y]!=g)rot((x==c[y][0])==(y==c[pre[y]][0])?y:x); if (g==0)root=x; } void inster(int x) { int y=root; while (c[y][x>data[y]])y=c[y][x>data[y]]; data[++tot]=x; c[tot][0]=c[tot][1]=0; pre[tot]=y; if (y)c[y][x>data[y]]=tot; splay(tot,0); } int findpre(int x) { int ans; for (int y=root;y;) if (data[y]<x)ans=data[y],y=c[y][1]; else y=c[y][0]; return ans; } int findnxt(int x) { int ans; for (int y=root;y;) if (data[y]<x)y=c[y][1]; else ans=data[y],y=c[y][0]; return ans; } int main() { scanf("%d%d",&n,&x); inster(x+N);in[x+N]=1; int ans=x,S=x+N,B=x+N; for (int i=1;i<n;i++) { scanf("%d",&x);x+=N; if (in[x])continue; int k=1e9; if (x>S)k=min(k,x-findpre(x)); if (x<B)k=min(k,findnxt(x)-x); ans+=k;S=min(S,x);B=max(B,x); inster(x);in[x]=1; } printf("%d",ans); }
以上是关于bzoj1588的主要内容,如果未能解决你的问题,请参考以下文章