Luogu P1110 報表統計
阿新 • • 發佈:2022-02-15
solution
\(\quad\)insert i k
就維護一個 vector
\(\quad\)MIN_GAP
每次插入會破壞一對關係,增加兩對關係。增加好說,破壞怎麼辦?
\(\quad\)我們可以維護兩個堆,一個堆記錄加入的數,一個堆記錄刪除的數,但要輸出時,如果兩個堆頂數值相同,那就不斷一起彈出即可。事實上這是一種很好的方法。
\(\quad\)MIN_SORT_GAP
就每次插入的時候找一下前驅後繼,然後更新值,這裡有一個小小的優化,就是當 MIN
取到 0 時,就不用再取更新了。
code
#include<bits/stdc++.h> #define int long long #define fo(i,j,k) for(register int i=j;i<=k;++i) #define fd(i,j,k) for(register int i=j;i>=k;--i) using namespace std; const int N=1000100,inf=(1<<31)-1; inline int read(){ int ret=0,f=0; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch='-') f=1;ch=getchar();} while(ch>='0' && ch<='9'){ret=(ret<<1)+(ret<<3)+ch-(1<<4)-(1<<5);ch=getchar();} return f?-ret:ret; } int root; int n,m,a[N],min_sg=inf; struct splay_tree{ int ch[N][2],fa[N],val[N],size[N],tot; #define lson ch[x][0] #define rson ch[x][1] inline int find_son(int x){return (x=ch[fa[x]][1]);} inline void update(int x){size[x]=size[lson]+size[rson]+1;} inline void connect(int x,int f,int son){fa[x]=f;ch[f][son]=x;} inline void rotate(int x){ int y=fa[x]; int z=fa[y]; int xson=find_son(x); int yson=find_son(y); int b=ch[x][xson^1]; connect(b,y,xson); connect(y,x,xson^1); connect(x,z,yson); update(y);update(x); } inline void splay(int x,int goal){ while(fa[x]!=goal){ int y=fa[x]; if(fa[y]=goal) rotate(x); else if(find_son(x)==find_son(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } if(!goal) root=x; } inline int pre(int k){ int now=root,minn=-inf; while(now){ if(val[now]<k && val[now]>minn){minn=val[now];} if(val[now]<k) now=ch[now][1]; else now=ch[now][0]; } return minn; } inline int nxt(int k){ int now=root,maxx=inf; while(now){ if(val[now]>k && val[now]<maxx){maxx=val[now];} if(val[now]>k) now=ch[now][0]; else now=ch[now][1]; } return maxx; } inline int find(int k){ int now=root; while(1){ if(val[now]==k) { splay(now,0); return now;} if(val[now]<k) now=ch[now][1]; else now=ch[now][0]; if(!now) return 0; } } int newnode(int k){ val[++tot]=k; size[tot]=1; return tot; } inline void insert(int k){ int p=find(k); if(p){splay(p,0);min_sg=0;return ;} int p1=find(pre(k)),p2=find(nxt(k)); splay(p1,0); splay(p2,p1); ch[p2][0]=newnode(k); fa[tot]=p2; update(p2);update(p1); } inline void init(){ root=1; tot=2; val[1]=-inf;val[2]=inf; ch[1][1]=2;fa[2]=1; size[1]=2;size[2]=1; } #undef lson #undef rson }t; vector<int> v[N]; priority_queue< int ,vector<int> ,greater<int> > p_in; priority_queue< int ,vector<int> ,greater<int> > p_del; signed main(){ // freopen("P1110_7.in","r",stdin); n=read();m=read(); t.init(); fo(i,1,n) { a[i]=read(); if(min_sg){ int y=a[i]; int t1=abs(y-t.pre(y)); int t2=abs(y-t.nxt(y)); min_sg=min(min(t1,t2),min_sg); } t.insert(a[i]); v[i].push_back(a[i]); } fo(i,1,n-1) p_in.push(abs(a[i]-a[i+1])); fo(i,1,m){ char op[13]; scanf("%s",op); int l=strlen(op); if(l==6){ int x=read(),y=read(); v[x].push_back(y); if(min_sg){ int t1=abs(y-t.pre(y)); int t2=abs(y-t.nxt(y)); min_sg=min(min(t1,t2),min_sg); } t.insert(y); p_in.push(abs(v[x][v[x].size()-2]-y)); p_in.push(abs(a[x+1]-y)); p_del.push(abs(v[x][v[x].size()-2]-a[x+1])); } else if(l==7){ while(p_in.size() && p_del.size() && (p_in.top()=p_del.top())){ p_in.pop(); p_del.pop(); } printf("%d\n",p_in.top()); } else{ printf("%d\n",min_sg); } } // cout<<t.tot<<endl; return 0; }