BZOJ1058: [ZJOI2007]报表统计

1058: [ZJOI2007]报表统计

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 1738  Solved: 606
[Submit][Status]

Description

小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作: INSERT i k 在原数列的第i个元素后面添加一个新元素k; 如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子) MIN_GAP 查询相邻两个元素的之间差值(绝对值)的最小值 MIN_SORT_GAP 查询所有元素中最接近的两个元素的差值(绝对值) 例如一开始的序列为 5 3 1 执行操作INSERT 2 9将得到: 5 3 9 1 此时MIN_GAP为2,MIN_SORT_GAP为2。 再执行操作INSERT 2 6将得到: 5 3 9 6 1 注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?

Input

第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。第二行为N个整数,为初始序列。接下来的M行每行一个操作,即“INSERT i k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。

Output

对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。

Sample Input

3 5
5 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP

Sample Output

2
2
1

HINT

 

对于30%的数据,N ≤ 1000 , M ≤ 5000 对于100%的数据,N , M ≤500000 对于所有的数据,序列内的整数不超过5*108。

 

Source

最近怎么老是遇见这种剧恶心的题目。。。这是专门恶心pascal选手呢吧?

。。。。。。。。。。。。。。。

写一个 树状数组计算当前插入位置,

写一个splay维护相邻的最小值,

再写一个treap求前驱、后继,

打一个快排预处理第一次的答案

。。。。。。。。。。。。。。。。

我写出来连变量名都不想写了。。。哪天想受虐的再过来调吧。。。

代码“

  1 var
  2   function min(x,y:longint):longint;
  3    begin
  4    if x<y then exit(x) else exit(y);
  5    end;
  6   function max(x,y:longint):longint;
  7    begin
  8    if x>y then exit(x) else exit(y);
  9    end;
 10 procedure sort(l,r:longint);
 11  var i,j,x,y:longint;
 12  begin
 13  i:=l;j:=r;x:=b[(i+j)>>1];
 14  repeat
 15   while b[i]<x do inc(i);
 16   while b[j]>x do dec(j);
 17   if i<=j then
 18    begin
 19    y:=b[i];b[i]:=b[j];b[j]:=y;
 20    inc(i);dec(j);
 21    end;
 22  until i>j;
 23  if i<r then sort(i,r);
 24  if j>l then sort(l,j);
 25  end;
 26 procedure pushup(x:longint);
 27  var l,r:longint;
 28  begin
 29  s[x]:=s[c[x,0]]+s[c[x,1]]+1;
 30  mi[x]:=min(pre[x],min(mi[c[x,0]],mi[c[x,1]]));
 31  end;
 32 procedure rotate(x:longint;var k:longint);inline;
 33  var y,z,l,r:longint;
 34  begin
 35   y:=fa[x];z:=fa[y];
 36   l:=ord(c[y,1]=x);r:=l xor 1;
 37   if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
 38   fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
 39   c[y,l]:=c[x,r];c[x,r]:=y;
 40   pushup(y);pushup(x);
 41  end;
 42 procedure splay(x:longint;var k:longint);inline;
 43  var y,z:longint;
 44  begin
 45   while x<>k do
 46    begin
 47     y:=fa[x];z:=fa[y];
 48     if y<>k then
 49      if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k)
 50      else rotate(y,k);
 51     rotate(x,k);
 52    end;
 53  end;
 54 function find(x,rank:longint):longint;inline;
 55  var l,r:longint;
 56  begin
 57   l:=c[x,0];r:=c[x,1];
 58   if s[l]+1=rank then exit(x)
 59   else if s[l]>=rank then exit(find(l,rank))
 60   else exit(find(r,rank-s[l]-1));
 61  end;
 62 procedure build(l,r,f:longint);inline;
 63  var x,y,z,mid:longint;
 64  begin
 65   if l>r then exit;
 66   mid:=(l+r)>>1;
 67   x:=id[mid];y:=id[f];
 68   v[x]:=a[mid];pre[x]:=abs(a[mid]-a[mid-1]);
 69   c[y,ord(mid>f)]:=x;fa[x]:=y;
 70   if l=r then
 71     begin
 72      s[x]:=1;mi[x]:=pre[x];
 73      exit;
 74     end;
 75   build(l,mid-1,mid);build(mid+1,r,mid);
 76   pushup(x);
 77  end;
 78 procedure split(l,r:longint;var x,y:longint);inline;
 79  begin
 80   x:=find(rt,l);y:=find(rt,r);
 81   splay(x,rt);splay(y,c[x,1]);
 82  end;
 83 procedure init;
 84  begin
 85    readln(n);
 86    a[1]:=-inf;a[n+1]:=-inf;
 87    for i:=2 to n+1 do begin read(a[i]);b[i]:=a[i];end;
 88    sort(1,n);
 89    ans:=maxlongint;
 90    for i:=2 to n do ans:=min(ans,b[i]-b[i-1]);
 91  end;
 92 procedure add(x:longint);
 93  begin
 94  while x<=n do
 95    begin
 96     inc(d[x]);
 97     inc(x,x and (-x));
 98    end;
 99  end;
100 function sum(x:longint):longint;
101  begin
102  sum:=0;
103  while x>0 do
104    begin
105     inc(sum,d[x]);
106     dec(x,x and (-x));
107    end;
108  end;
109 procedure l_rotate(var x:longint);
110 var
111   y:longint;
112 begin
113   y:=r[x];
114   r[x]:=l[y];
115   l[y]:=x;
116   x:=y;
117 end;
118 procedure r_rotate(var x:longint);
119 var
120   y:longint;
121 begin
122   y:=l[x];
123   l[x]:=r[y];
124   r[y]:=x;
125   x:=y;
126 end;
127 
128 procedure insert(var k,key:longint);
129 begin
130   if k=0 then
131     begin
132       inc(m);
133       vv[m]:=key;
134       hr[m]:=random(maxlongint);
135       k:=m;
136       exit;
137     end;
138   if key<=vv[k] then
139     begin
140       insert(l[k],key);
141       if hr[l[k]]>hr[k] then
142         r_rotate(k);
143       exit;
144     end;
145   if key>vv[k] then
146     begin
147       insert(r[k],key);
148       if hr[r[k]]>hr[k] then
149         l_rotate(k);
150       exit;
151     end;
152 end;
153 function pred(var t,key:longint):longint;
154 begin
155    if t=0 then
156       exit(-1);
157    if key<=vv[t] then
158       pred:=pred(l[t],key)
159    else begin
160       pred:=pred(r[t],key);
161       if pred=-1 then
162          pred:=vv[t];
163    end;
164 end;
165 function succ(var t,key:longint):longint;
166 begin
167    if t=0 then
168       exit(-1);
169    if vv[t]<=key then
170       succ:=succ(r[t],key)
171    else begin
172       succ:=succ(l[t],key);
173       if succ=-1 then
174          succ:=vv[t];
175    end;
176 end;
177 procedure solveinsert;
178  begin
179   readln(pos,val);
180   l:=sum(pos)+pos;r:=l+2;split(l,r,x,y);
181   inc(tot);
182   c[y,0]:=tot;fa[tot]:=y;s[tot]:=1;
183   v[tot]:=val;pre[tot]:=abs(v[tot]-v[x]);mi[tot]:=pre[tot];
184   pre[y]:=abs(v[y]-v[tot]);
185   pushup(y);pushup(x);
186   add(pos);
187   ans:=min(ans,abs(pred(root,val)-val));
188   ans:=min(ans,abs(succ(root,val)-val));
189   insert(root,val);
190  end;
191 procedure main;
192  begin
193    for i:=1 to n+2 do id[i]:=i;
194    for i:=2 to n+1 do insert(root,a[i]);
195    build(1,n+2,0);rt:=(n+3)>>1;
196    for i:=1 to m do
197     begin
198     reac(ch,ch,ch,ch,ch);
199     case ch of
200     'R':solveinsert;
201     'G':writeln(mi[rt]);
202     'S':writeln(ans);
203     end;
204     end;
205  end;
206 begin
207   assign(input,'input.txt');assign(output,'output.txt');
208   reset(input);rewrite(output);
209   init;
210   main;
211   close(input);close(output);
212 end.    
View Code

 

posted @ 2014-08-11 19:50  ZYF-ZYF  Views(267)  Comments(0Edit  收藏  举报