P1110 [ZJOI2007]报表统计

P1110 [ZJOI2007]报表统计

动态插入,然后询问相邻差的绝对值最小值的全局值域相邻差的绝对值最小值。

直接分别用两个平衡树维护即可。

题解代码:

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
#define son(x) (x==ch[fa[x]][1])
using namespace std;
using namespace __gnu_pbds;
const int N=1e6+5;
int n,m,a[N<<1][2],tot,val[N<<1];
int root,ch[N][2],fa[N],cnt,date[N];
int minn=0x7fffffff;
struct node{
    int ls,rs,val;
    bool operator < (const node &a) const {return val>a.val;}
};
typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap;
heap q;
heap::point_iterator id[N];
int gi(){
    int a=0;char x=getchar();bool f=0;
    while((x<'0'||x>'9')&&x!='-') x=getchar();
    if(x=='-') x=getchar(),f=1;
    while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();
    return f?-a:a;
}
void rotate(int x){
    int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
    z?ch[z][c]=x:root=x; fa[x]=z;
    if(a) fa[a]=y; ch[y][b]=a;
    ch[x][!b]=y,fa[y]=x;
}
void splay(int x,int i){
    while(fa[x]!=i){
        RE int y=fa[x],z=fa[y];
        if(z==i) rotate(x);
        else {
            if(son(x)==son(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
    }
}

void insert(int &rt,int x){
    if(!rt){rt=++cnt,date[cnt]=x;return;}
    if(date[rt]==x){minn=0;return;}
    if(x<date[rt]) insert(ch[rt][0],x),fa[ch[rt][0]]=rt,minn=min(minn,abs(date[rt]-x));
    else insert(ch[rt][1],x),fa[ch[rt][1]]=rt,minn=min(minn,abs(date[rt]-x));    
}

int main(){
    int pos,x; char s[10];
    n=gi(),m=gi(),tot=n;
    For(i,1,n) {
        val[i]=gi(),insert(root,val[i]),splay(cnt,0);
        if(i!=1) a[i][0]=i;
        if(i!=n) a[i][1]=i;
    }
    For(i,2,n) id[i]=q.push(node{i,i+1,abs(val[i]-val[i-1])});
    while(m--){
        scanf("%s",s);
        if(s[0]=='I') {
            pos=gi(),val[++tot]=gi(),insert(root,val[tot]),splay(cnt,0);
            int tp=a[pos][1];
            id[tot]=q.push(node{tot,tp,abs(val[tp]-val[tot])});
            if(pos!=n) q.modify(id[pos+1],node{pos+1,tot,abs(val[pos+1]-val[tot])});
            a[pos+1][0]=tot,a[pos][1]=tot;
        }
        else if(strlen(s)==7) printf("%d
",q.top().val);
        else printf("%d
",minn);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Akmaey/p/14668785.html