BZOJ 1058 [ZJOI2007]报表统计 Splay

这个题真是不爽,人家set又短又快,我这个又长又慢,差十几毫秒tle。。。

我是一个splay维护相邻的最差小值,一个是维护全局最小差值(在插入的时候用前驱和后继更新)

 

 

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <cstdlib>
  6 #include <cmath>
  7 
  8 #define N 2222222
  9 #define INF 1LL<<60
 10 
 11 using namespace std;
 12 
 13 long long msg,num[N],val[N],a[N],b[N];
 14 int fa[N],son[N][2];
 15 int tot,cnt,root1,root2;
 16 int q[N],top;
 17 int n,m;
 18 int hs[N],lt[N],rt[N];
 19 
 20 inline void prt(int x)
 21 {
 22     if(!x) return;
 23     prt(son[x][0]);
 24     printf("%lld    ",val[x]);
 25     prt(son[x][1]);
 26 }
 27 
 28 inline void link(int x,int y,int c)
 29 {
 30     fa[x]=y; son[y][c]=x;
 31 }
 32 
 33 inline void rotate(int x,int c)
 34 {
 35     int y=fa[x];
 36     link(x,fa[y],son[fa[y]][1]==y);
 37     link(son[x][!c],y,c);
 38     link(y,x,!c);
 39 }
 40 
 41 inline void splay(int x,int g,int &rt)
 42 {
 43     while(fa[x]!=g)
 44     {
 45         int y=fa[x];
 46         int cy=son[fa[y]][1]==y,cx=son[y][1]==x;
 47         if(fa[y]==g) rotate(x,cx);
 48         else
 49         {
 50             if(cx==cy) rotate(y,cy);
 51             else rotate(x,cx);
 52             rotate(x,cy);
 53         }
 54     }
 55     if(!g) rt=x;
 56 }
 57 
 58 inline int getnum()
 59 {
 60     if(top) return q[top--];
 61     return ++cnt;
 62 }
 63 
 64 inline void newnode(int y,int &x,long long sp)
 65 {
 66     x=getnum();
 67     fa[x]=y; val[x]=sp;
 68     son[x][0]=son[x][1]=0;
 69 }
 70 
 71 inline void init()
 72 {
 73     newnode(cnt=0,root1,-INF);
 74     newnode(root1,son[root1][1],INF);
 75     newnode(0,root2,-INF);
 76     newnode(root2,son[root2][1],INF);
 77 }
 78 
 79 inline void build(int &u,int l,int r,int f)
 80 {
 81     if(l>r) return;
 82     int mid=(l+r)>>1;
 83     newnode(f,u,a[mid]);
 84     build(son[u][0],l,mid-1,u);
 85     build(son[u][1],mid+1,r,u);
 86 }
 87 
 88 inline void insert(long long sp,int &rt)
 89 {
 90     int x=rt;
 91     while(son[x][sp>val[x]]) x=son[x][sp>val[x]];
 92     newnode(x,son[x][sp>val[x]],sp);
 93     splay(son[x][sp>val[x]],0,rt);
 94 }
 95 
 96 inline int find(long long sp,int rt)
 97 {
 98     int x=rt;
 99     while(x)
100     {
101         if(val[x]==sp) return x;
102         x=son[x][sp>val[x]];
103     }
104 }
105 
106 inline int getmax(int x)
107 {
108     while(son[x][1]) x=son[x][1];
109     return x;
110 }
111 
112 inline int getmin(int x)
113 {
114     while(son[x][0]) x=son[x][0];
115     return x;
116 }
117 
118 inline void del(long long sp,int &rt)
119 {
120     int z=find(sp,rt),x,y;
121     splay(z,0,rt);
122     x=getmax(son[z][0]);
123     y=getmin(son[z][1]);
124     splay(x,0,rt); splay(y,x,rt);
125     q[++top]=son[y][0];
126     fa[son[y][0]]=0;
127     son[y][0]=0;
128 }
129 
130 inline void go()
131 {
132     msg=INF;
133     scanf("%d%d",&n,&m);
134     for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
135     for(int i=1;i<n;i++) a[i]=abs(b[i+1]-b[i]);
136     sort(a+1,a+n);
137     init();
138     build(son[son[root1][1]][0],1,n-1,son[root1][1]);
139     for(int i=1;i<=n;i++) a[i]=b[i];
140     sort(a+1,a+1+n);
141     for(int i=1;i<n;i++) msg=min(msg,abs(a[i]-a[i+1]));
142     build(son[son[root2][1]][0],1,n,son[root2][1]);
143     for(int i=1;i<=n;i++)
144     {
145         num[i]=b[i]; hs[i]=i;
146         lt[i]=i-1; rt[i-1]=i;
147         lt[i+1]=i; rt[i]=i+1;
148     }
149     tot=n+1;
150     char str[14]; int c; long long d;
151     while(m--)
152     {
153         scanf("%s",str);
154         if(str[0]=='I')
155         {
156             scanf("%d%lld",&c,&d);
157             insert(d,root2);
158             if(msg!=0)
159             {
160                 int x=getmax(son[root2][0]),y=getmin(son[root2][1]);
161                 msg=min(msg,min(abs(val[x]-d),abs(val[y]-d)));
162             }
163             if(rt[hs[c]]!=n+1) del(abs(num[hs[c]]-num[rt[hs[c]]]),root1);
164             ++tot; num[tot]=d;
165             lt[tot]=hs[c]; lt[rt[hs[c]]]=tot;
166             rt[tot]=rt[hs[c]]; rt[hs[c]]=tot;
167             hs[c]=tot;
168             if(lt[hs[c]]!=0) insert(abs(num[hs[c]]-num[lt[hs[c]]]),root1);
169             if(rt[hs[c]]!=n+1) insert(abs(num[hs[c]]-num[rt[hs[c]]]),root1);
170         }
171         else if(str[4]=='G')
172         {
173             splay(1,0,root1);splay(2,1,root1);
174             printf("%lld\n",val[getmin(son[2][0])]);
175         }
176         else printf("%lld\n",msg);
177     }
178 }
179     
180 
181 int main()
182 {
183     go();
184     return 0;
185 }

 

 

posted @ 2013-03-13 00:05  proverbs  阅读(...)  评论(... 编辑 收藏