1058: [ZJOI2007]报表统计 - BZOJ

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。

 

囧,又是splay,又被卡常数了,每次基本上都是对着数据调才调过的

我用两颗splay树,一个存所有的数(每次查前驱和后继更新答案),一个存所有的差值

当minsortgap为0时就不用再更新它了,还有,因为相邻的差值有一部分是不会被删除的,所以用min记录这些值中最小的值,大于等于min的差值就不用管它了(既不用删除,也不用插入)

搞了这么久终于过了(不过很慢,1300ms+)

  1 const

  2     maxn=500010;

  3 type

  4     node=record

  5       son:array[0..1]of longint;

  6       x,count,fa:longint;

  7     end;

  8 var

  9     tree:array[0..maxn*10]of node;

 10     a,b:array[0..maxn]of longint;

 11     n,m,mingap,minsortgap,min,tot,root1,root2:longint;

 12     flag:boolean;

 13  

 14 procedure down(var x:longint;y:longint);

 15 begin

 16     if x>y then x:=y;

 17 end;

 18  

 19 procedure rotate(x,w:longint;var root:longint);

 20 var

 21     y:longint;

 22 begin

 23     y:=tree[x].fa;

 24     tree[y].son[w]:=tree[x].son[w xor 1];

 25     if tree[x].son[w xor 1]<>0 then tree[tree[x].son[w xor 1]].fa:=y;

 26     tree[x].son[w xor 1]:=y;

 27     if root=y then root:=x

 28     else

 29       if tree[tree[y].fa].son[0]=y then tree[tree[y].fa].son[0]:=x

 30       else tree[tree[y].fa].son[1]:=x;

 31     tree[x].fa:=tree[y].fa;

 32     tree[y].fa:=x;

 33 end;

 34  

 35 procedure splay(x,z:longint;var root:longint);

 36 var

 37     y:longint;

 38 begin

 39     while tree[x].fa<>z do

 40       begin

 41         y:=tree[x].fa;

 42         if tree[y].fa=z then

 43           if tree[y].son[0]=x then rotate(x,0,root)

 44           else rotate(x,1,root)

 45         else

 46           if tree[tree[y].fa].son[0]=y then

 47             if tree[y].son[0]=x then

 48               begin

 49                 rotate(y,0,root);

 50                 rotate(x,0,root);

 51               end

 52             else

 53               begin

 54                 rotate(x,1,root);

 55                 rotate(x,0,root);

 56               end

 57           else

 58             if tree[y].son[0]=x then

 59               begin

 60                 rotate(x,0,root);

 61                 rotate(x,1,root);

 62               end

 63             else

 64               begin

 65                 rotate(y,1,root);

 66                 rotate(x,1,root);

 67               end;

 68       end;

 69 end;

 70  

 71 function pre(now:longint):longint;

 72 begin

 73     now:=tree[now].son[0];

 74     while tree[now].son[1]<>0 do

 75       now:=tree[now].son[1];

 76     exit(now);

 77 end;

 78  

 79 function succ(now:longint):longint;

 80 begin

 81     now:=tree[now].son[1];

 82     while tree[now].son[0]<>0 do

 83       now:=tree[now].son[0];

 84     exit(now);

 85 end;

 86  

 87 procedure delete(x:longint);

 88 var

 89     now,l,r:longint;

 90 begin

 91     now:=root2;

 92     while true do

 93       begin

 94         if now=0 then exit;

 95         if tree[now].x=x then break;

 96         if tree[now].x>x then now:=tree[now].son[0]

 97         else now:=tree[now].son[1];

 98       end;

 99     splay(now,0,root2);

100     if tree[root2].count>1 then dec(tree[root2].count)

101     else

102       begin

103         if (tree[root2].son[0]=0) or (tree[root2].son[1]=0) then

104         begin

105           if tree[root2].son[1]<>0 then mingap:=tree[succ(root2)].x;

106           root2:=tree[root2].son[0]+tree[root2].son[1];

107           tree[root2].fa:=0;

108           exit;

109         end;

110         l:=pre(root2);

111         r:=succ(root2);

112         splay(l,0,root2);

113         splay(r,l,root2);

114         tree[r].son[0]:=0;

115       end;

116 end;

117  

118 procedure insert(x:longint;var root:longint);

119 var

120     now:longint;

121 begin

122     now:=root;

123     if root=0 then

124     begin

125       inc(tot);

126       root:=tot;

127       tree[tot].x:=x;

128       tree[tot].count:=1;

129       if root=root2 then down(mingap,x);

130       exit;

131     end;

132     while true do

133       begin

134         if tree[now].x=x then

135           if root=root1 then

136             begin

137               minsortgap:=0;

138               flag:=true;

139               exit;

140             end

141           else

142             begin

143               inc(tree[now].count);

144               exit;

145             end;

146         if tree[now].x>x then

147           if tree[now].son[0]=0 then break

148           else now:=tree[now].son[0]

149         else

150           if tree[now].son[1]=0 then break

151           else now:=tree[now].son[1];

152       end;

153     inc(tot);

154     tree[tot].x:=x;

155     tree[tot].count:=1;

156     if x<tree[now].x then tree[now].son[0]:=tot

157     else tree[now].son[1]:=tot;

158     tree[tot].fa:=now;

159     splay(tot,0,root);

160     if root=root1 then

161       begin

162         if tree[root].son[0]<>0 then down(minsortgap,tree[root].x-tree[pre(root)].x);

163         if tree[root].son[1]<>0 then down(minsortgap,tree[succ(root)].x-tree[root].x);

164       end

165     else down(mingap,x);

166 end;

167  

168 procedure init;

169 var

170     i:longint;

171 begin

172     read(n,m);

173     minsortgap:=maxlongint;

174     mingap:=maxlongint;

175     min:=maxlongint;

176     for i:=1 to n do

177       begin

178         read(a[i]);

179         b[i]:=a[i];

180         if flag=false then insert(a[i],root1);

181         if i>1 then insert(abs(a[i]-a[i-1]),root2);

182       end;

183     readln;

184 end;

185  

186 procedure work;

187 var

188     i,x,y:longint;

189     c:char;

190     s:string;

191 begin

192     for i:=1 to m do

193       begin

194         read(c);

195         case c of

196           'I':begin

197             readln(c,c,c,c,c,x,y);

198             if x<n then

199             begin

200               if min>abs(b[x+1]-y) then insert(abs(b[x+1]-y),root2);

201               if min>abs(a[x]-b[x+1]) then delete(abs(a[x]-b[x+1]));

202             end;

203             down(min,abs(a[x]-y));

204             if flag=false then insert(y,root1);

205             a[x]:=y;

206           end;

207           'M':begin

208             readln(s);

209             if length(s)>7 then writeln(minsortgap)

210             else

211               begin

212                 down(mingap,min);

213                 writeln(mingap);

214               end;

215           end;

216         end;

217       end;

218 end;

219  

220 begin

221     init;

222     work;

223 end.
View Code

 

你可能感兴趣的:(2007)