码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1588

时间:2017-11-21 19:47:55      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:else   space   scanf   oid   color   return   printf   bit   for   

题解:

我们发现,今天的波动=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

标签:else   space   scanf   oid   color   return   printf   bit   for   

原文地址:http://www.cnblogs.com/xuanyiming/p/7874827.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!