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 }

 

 

你可能感兴趣的:(2007)