题解 P1110 【[ZJOI2007]报表统计】

Treeloveswater

2017-05-06 19:30:16

Solution

超级大水题。竟然是省选难度的? 一棵无比简单的连update都不用写的splay+一个带删除的堆,完美搞定。 操作一:没必要搞一棵splay。我们只用开一个lq[500001][2]的数组记录这个点的前面和后面就行。 操作二:带修改的小根堆 操作三:把所有数扔到splay里,按大小为关键字,再插入的时候取个max的差值就好了。 完美解决,特别好写~ 完结,撒花~ ```cpp #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int tot,n,m,a,k,minans=1e7; struct node { int data; node *son[2],*pre; bool judge(); void setson(node *child,int lr); }pool[1000001],*null,*root; int heap1[1500001],delheap[1000001],lq[500001][3]; char s[25]; bool node::judge(){return pre->son[1]==this;} void node::setson(node *child,int lr){son[lr]=child;if(child!=null)child->pre=this;} node *getnew(int value) { node *now=pool+ ++tot; now->data=value; now->pre=now->son[1]=now->son[0]=null; return now; } int ab(int x) { return x<0?-x:x; } void rotate(node *&now) { node *dad=now->pre,*grandfa=now->pre->pre; int lr=now->judge(); dad->setson(now->son[lr^1],lr); now->setson(dad,lr^1); now->pre=grandfa; if(grandfa!=null) grandfa->son[grandfa->son[1]==dad?1:0]=now; } void splay(node *now,node *tar) { for(;now->pre!=null;rotate(now)) if(now->pre->pre!=tar) now->judge()==now->pre->judge()?rotate(now->pre):rotate(now); if(tar==null)root=now; } void in(int *heap,int value) { heap[++heap[0]]=value; int now=heap[0],nxt; while(now>1) { nxt=now>>1; if(heap[nxt]<heap[now])break; swap(heap[nxt],heap[now]); now=nxt; } } void del(int *heap) { heap[1]=heap[heap[0]--]; int now=1,nxt; while(now*2<=heap[0]) { nxt=now<<1; if(heap[nxt]>heap[nxt+1]&&nxt<heap[0])nxt++; if(heap[now]<heap[nxt])break; swap(heap[now],heap[nxt]); now=nxt; } } void insert(int value) { node *newone=getnew(value); node *now=root,*last=null; while(now!=null) { last=now; if(ab(newone->data-now->data)<minans)minans=ab(newone->data-now->data); if(now->data>=newone->data) now=now->son[0]; else now=now->son[1]; } if(last==null) root=newone; else { if(ab(newone->data-last->data)<minans)minans=ab(newone->data-last->data); if(last->data>=newone->data) last->setson(newone,0); else last->setson(newone,1); } } int main() { null=pool; null->data=0; null->pre=null->son[1]=null->son[0]=null; root=null; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&lq[i][1]); lq[i][2]=lq[i][1]; if(i>1)in(heap1,ab(lq[i][1]-lq[i-1][2])); insert(lq[i][1]); } for(int i=1;i<=m;i++) { scanf("%s",s); if(s[0]=='I') { scanf("%d%d",&a,&k); if(a<n) { in(delheap,ab(lq[a][2]-lq[a+1][1])); in(heap1,ab(k-lq[a+1][1])); } in(heap1,ab(k-lq[a][2])); lq[a][2]=k; insert(k); } else { int length=strlen(s); if(length<10) { while(heap1[1]==delheap[1]) { del(heap1); del(delheap); } printf("%d\n",heap1[1]); } else printf("%d\n",minans); } } } ```