TYVJ 1730 二逼平衡树 线段树套平衡树

没什么好说的。。被坑了。。

查询排名为k的数时,二分这个数,转化成查找w的排名。

若w这个数不存在,就先插入w,然后把w旋转到根,既可以求w的排名。

 

View Code
  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdio>

  4 #include <cstdlib>

  5 #include <algorithm>

  6 

  7 #define INF 100000000

  8 #define N 1110000

  9 #define BUG system("pause")

 10 

 11 using namespace std;

 12 

 13 int sz[N],fa[N],son[N][2],val[N],root[N];

 14 int n,cnt,m;

 15 int a[N],b[N];

 16 int opt,sq,sum,suc,pre,pos;

 17 int q[N],tot;

 18 

 19 struct ST

 20 {

 21     int l,r;

 22 }T[N<<2];

 23 

 24 inline void prt(int x)

 25 {

 26     if(!x) return;

 27     prt(son[x][0]);

 28     printf("%d   ",val[x]);

 29     prt(son[x][1]);

 30 }

 31 

 32 inline void pushup(int x)

 33 {

 34     if(!x) return;

 35     sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;

 36 }

 37 

 38 inline void link(int x,int y,int c)

 39 {

 40     fa[x]=y; son[y][c]=x;

 41 }

 42 

 43 void rotate(int x,int c)

 44 {

 45     int y=fa[x];

 46     link(x,fa[y],son[fa[y]][1]==y);

 47     link(son[x][!c],y,c);

 48     link(y,x,!c);

 49     pushup(y);

 50 }

 51 

 52 void splay(int x,int g,int &rt)

 53 {

 54     while(fa[x]!=g)

 55     {

 56         int y=fa[x];

 57         int cy=(son[fa[y]][1]==y),cx=(son[y][1]==x);

 58         if(fa[y]==g) rotate(x,cx);

 59         else

 60         {

 61             if(cx==cy) rotate(y,cy);

 62             else rotate(x,cx);

 63             rotate(x,cy);

 64         }    

 65     }

 66     pushup(x);

 67     if(!g) rt=x;

 68 }

 69 

 70 inline int getnum()

 71 {

 72     if(tot) return q[tot--];

 73     return ++cnt;

 74 }

 75 

 76 inline void newnode(int y,int &x,int sp)

 77 {

 78     x=getnum();

 79     fa[x]=y; val[x]=sp; sz[x]=1;

 80     son[x][1]=son[x][0]=0;

 81 }

 82 

 83 inline void pack(int &u,int l,int r,int f)

 84 {

 85     if(r<l) return;

 86     int mid=(l+r)>>1;

 87     newnode(f,u,a[mid]);

 88     pack(son[u][0],l,mid-1,u);

 89     pack(son[u][1],mid+1,r,u);

 90     pushup(u);

 91 }

 92 

 93 inline void bsplay(int u,int l,int r)

 94 {

 95     newnode(0,root[u],-INF);

 96     newnode(root[u],son[root[u]][1],INF);

 97     sz[root[u]]=2;

 98     pack(son[son[root[u]][1]][0],l,r,son[root[u]][1]);

 99     pushup(son[son[root[u]][1]][0]); pushup(son[root[u]][1]);

100 }

101 

102 inline void build(int u,int l,int r)

103 {

104     T[u].l=l; T[u].r=r;

105     if(l==r)

106     {

107         bsplay(u,l,r);

108         return;

109     }

110     int mid=(l+r)>>1;

111     build(u<<1,l,mid); 

112     build(u<<1|1,mid+1,r);

113     sort(a+l,a+r+1);

114     bsplay(u,l,r);

115 }

116 

117 inline void read()

118 {

119     scanf("%d%d",&n,&m);

120     for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];

121     build(1,1,n);

122 }

123 

124 inline int find(int sp,int x)

125 {

126     while(x)

127     {

128         if(val[x]==sp) return x;

129         x=son[x][val[x]<sp];

130     }

131 }

132 

133 inline int getmin(int x)

134 {

135     while(son[x][0]) x=son[x][0];

136     return x;

137 }

138 

139 inline int getmax(int x)

140 {

141     while(son[x][1]) x=son[x][1];

142     return x;

143 }

144 

145 inline void insert(int sp,int &rt)

146 {

147     int x=rt;

148     while(son[x][val[x]<sp]) x=son[x][val[x]<sp];

149     newnode(x,son[x][val[x]<sp],sp);

150     splay(son[x][val[x]<sp],0,rt);

151 }

152 

153 inline void del(int sp,int &rt)

154 {

155     int x=find(sp,rt);

156     splay(x,0,rt);

157     int y=getmax(son[x][0]),z=getmin(son[x][1]);

158     splay(y,0,rt); splay(z,y,rt);

159     q[++tot]=son[z][0]; son[z][0]=0;

160     pushup(z); pushup(y);

161 }

162 

163 inline int pred(int x,int sp)

164 {

165     int re=-INF;

166     while(x)

167     {

168         if(val[x]<sp) re=max(val[x],re);

169         x=son[x][val[x]<sp];

170     }

171     return re;

172 }

173 

174 inline int succ(int x,int sp)

175 {

176     int re=INF;

177     while(x)

178     {

179         if(val[x]>sp) re=min(val[x],re);

180         x=son[x][val[x]<=sp];//!!!!!

181     }

182     return re;

183 }

184 

185 inline void query(int u,int l,int r)

186 {

187     if(T[u].l>=l&&T[u].r<=r)

188     {

189         if(opt==1)

190         {

191             insert(sq,root[u]);

192             sum+=sz[son[root[u]][0]]-1;

193             del(sq,root[u]);

194         }

195         else if(opt==3)

196         {

197             del(b[pos],root[u]);

198             insert(sq,root[u]);

199         }

200         else if(opt==4)

201         {

202             pre=max(pre,pred(root[u],sq));

203         }

204         else

205         {

206             suc=min(suc,succ(root[u],sq));

207         }

208         return;

209     }

210     int mid=(T[u].l+T[u].r)>>1;

211     if(r<=mid) query(u<<1,l,r);

212     else if(l>mid) query(u<<1|1,l,r);

213     else query(u<<1,l,mid),query(u<<1|1,mid+1,r);

214     if(opt==3)

215     {

216         del(b[pos],root[u]);

217         insert(sq,root[u]);

218     }

219 }

220 

221 inline void go()

222 {

223     for(int i=1,aa,bb,k;i<=m;i++)

224     {

225         scanf("%d",&opt);

226         if(opt==1)

227         {

228             scanf("%d%d%d",&aa,&bb,&sq);

229             sum=0;

230             query(1,aa,bb);

231             printf("%d\n",sum+1);

232         }

233         else if(opt==2)

234         {

235             scanf("%d%d%d",&aa,&bb,&k);

236             opt=1;

237             int l=0,r=INF,ans;

238             while(l<=r)

239             {

240                 int mid=(l+r)>>1;

241                 sum=0;

242                 sq=mid; query(1,aa,bb);

243                 if(sum+1<=k) ans=mid,l=mid+1;

244                 else r=mid-1;

245             }

246             printf("%d\n",ans);

247         }

248         else if(opt==3)

249         {

250             scanf("%d%d",&pos,&sq);

251             query(1,pos,pos);

252             b[pos]=sq;

253         }

254         else if(opt==4)

255         {

256             scanf("%d%d%d",&aa,&bb,&sq);

257             pre=-INF;

258             query(1,aa,bb);

259             printf("%d\n",pre);

260         }

261         else

262         {

263             scanf("%d%d%d",&aa,&bb,&sq);

264             suc=INF;

265             query(1,aa,bb);

266             printf("%d\n",suc);

267         }

268     }

269 }

270 

271 int main()

272 {

273     read(),go();

274     return 0;

275 }

 

 

 

你可能感兴趣的:(线段树)