3600: 没有人的算术
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 616 Solved: 280
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
Sample Output
HINT
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
const int maxm = 5E5 + 50;
const int T = 4;
typedef double DB;
const DB alpha = 0.666;
const DB eps = 1E-9;
DB lp,rp,siz[maxm],phi[maxm],L[maxm],R[maxm];
int n,m,cnt,rt,tp,p,Now,Ans,fa[maxm],id[maxn*T]
,pos[maxn*T],ch[maxm][2],s[maxm],lc[maxm],rc[maxm];
int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
int getcom()
{
char ch = getchar();
while (ch != 'C' && ch != 'Q') ch = getchar();
return ch == 'C' ? 1 : 2;
}
int cmp(const int &x,const int &y)
{
if (lc[x] == lc[y] && rc[x] == rc[y]) return 2;
if (lc[x] == lc[y]) return phi[rc[x]] < phi[rc[y]] ? 1 : 0;
return phi[lc[x]] < phi[lc[y]] ? 1 : 0;
}
void maintain(int o)
{
int ls = (o<<1),rs = (o<<1|1);
int d = cmp(id[ls],id[rs]);
if (d == 1) pos[o] = pos[rs],id[o] = id[rs];
else pos[o] = pos[ls],id[o] = id[ls];
}
void Build(int o,int l,int r)
{
if (l == r) {id[o] = 1; pos[o] = l; return;}
int mid = (l + r) >> 1;
Build(o<<1,l,mid); Build(o<<1|1,mid+1,r);
maintain(o);
}
void Modify(int o,int l,int r,int k,int ID)
{
if (l == r) {id[o] = ID; return;}
int mid = (l + r) >> 1;
if (k <= mid) Modify(o<<1,l,mid,k,ID);
else Modify(o<<1|1,mid+1,r,k,ID);
maintain(o);
}
int Get_id(int o,int l,int r,int k)
{
if (l == r) return id[o]; int mid = (l + r) >> 1;
if (k <= mid) return Get_id(o<<1,l,mid,k);
else return Get_id(o<<1|1,mid+1,r,k);
}
void Get_pos(int o,int l,int r,int ql,int qr)
{
if (ql <= l && r <= qr)
{
int d = cmp(id[o],Now);
if (d == 0) Now = id[o],Ans = pos[o];
else if (d == 2) Ans = min(Ans,pos[o]);
return;
}
int mid = (l + r) >> 1;
if (ql <= mid) Get_pos(o<<1,l,mid,ql,qr);
if (qr > mid) Get_pos(o<<1|1,mid+1,r,ql,qr);
}
int Query(int x,int now)
{
if (!x) return x;
int d = cmp(x,now);
if (d == 2) return x;
return Query(ch[x][d],now);
}
void Insert(int &x,int now,DB LP,DB RP)
{
if (!x)
{
x = now; phi[x] = (LP + RP) / 2.00;
L[x] = LP; R[x] = RP; siz[x] = 1.00; return;
}
DB mid = (LP + RP) / 2.00; int d = cmp(x,now);
if (!d) Insert(ch[x][d],now,L[x],mid);
else Insert(ch[x][d],now,mid,R[x]);
fa[ch[x][d]] = x; siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1.00;
if (siz[ch[x][d]] >= alpha * siz[x]) p = x,lp = L[x],rp = R[x];
}
void Dfs(int x)
{
if (!x) return; Dfs(ch[x][0]);
s[++tp] = x; Dfs(ch[x][1]);
}
int Build_tree(int l,int r,DB LP,DB RP)
{
if (l > r) return 0;
int mid = (l + r) >> 1;
int k = s[mid]; phi[k] = (LP + RP) / 2.00;
ch[k][0] = Build_tree(l,mid-1,LP,phi[k]);
ch[k][1] = Build_tree(mid+1,r,phi[k],RP);
siz[k] = 1.00; L[k] = LP; R[k] = RP;
for (int i = 0; i < 2; i++)
if (ch[k][i]) fa[ch[k][i]] = k,siz[k] += siz[ch[k][i]];
return k;
}
void Rebuild()
{
tp = 0; Dfs(p);
int q = fa[p],now = Build_tree(1,tp,lp,rp);
if (!q) rt = now,fa[now] = 0;
else ch[q][ch[q][1] == p] = now,fa[now] = q;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint(); m = getint(); rt = cnt = 1;
R[rt] = 1E9; phi[rt] = (L[rt] + R[rt]) / 2.00; Build(1,1,n);
while (m--)
{
int typ = getcom(),l,r;
l = getint(); r = getint();
if (typ == 1)
{
int k = getint(); ++cnt;
lc[cnt] = Get_id(1,1,n,l);
rc[cnt] = Get_id(1,1,n,r);
int ret = Query(rt,cnt);
if (ret) Modify(1,1,n,k,ret),--cnt;
else
{
Modify(1,1,n,k,cnt);
p = 0; Insert(rt,cnt,L[rt],R[rt]);
if (p) Rebuild();
}
}
else
{
Now = 1; Ans = maxn;
Get_pos(1,1,n,l,r); printf("%d\n",Ans);
}
}
return 0;
}