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 }
没有人能阻止我前进的步伐,除了我自己!