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的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1588: [HNOI2002]营业额统计

BZOJ1588_营业额统计_KEY

bzoj1588: [HNOI2002]营业额统计 splay瞎写

BZOJ1588

BZOJ 1588: Treap 模板

bzoj1588