可持久化平衡树 TLE
  • 板块CF702F T-Shirts
  • 楼主ZepX_D
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/5/14 09:14
  • 上次更新2024/5/14 16:01:53
查看原帖
可持久化平衡树 TLE
464004
ZepX_D楼主2024/5/14 09:14

rt,感觉 merge 的时候也没啥问题啊

#include <bits/stdc++.h>
#define LL long long

using namespace std;

const int N = 2e5+5;
struct node{int c,q;}a[N];
int cnt,ls[N<<7],rs[N<<7],laz[N<<7],s[N<<7],rt[N];
LL siz[N<<7];
mt19937_64 rnd(time(0));

bool cmp(node a,node b)
{return a.q == b.q ? a.c < b.c : a.q > b.q;}

void pushup(int i)
{siz[i] = siz[ls[i]]+siz[rs[i]]+1;}

void copy(int x,int y)
{ls[x] = ls[y],rs[x] = rs[y],siz[x] = siz[y],laz[x] = laz[y],s[x] = s[y];}

void down(int i)
{
	if(ls[i])
	{
		copy(++cnt,ls[i]);ls[i] = cnt;
		laz[ls[i]] += laz[i],s[ls[i]] += laz[i];
	}
	if(rs[i])
	{
		copy(++cnt,rs[i]);rs[i] = cnt;
		laz[rs[i]] += laz[i],s[rs[i]] += laz[i];
	}
	laz[i] = 0;
}

void split(int i,int k,int &x,int &y)
{
	if(!i) return (void)(x = y = 0);
	if (laz[i]) down(i);
	copy(++cnt,i),i = cnt;
	if(siz[ls[i]]+1 <= k) {x = i;split(rs[i],k-siz[ls[i]]-1,rs[i],y);pushup(x);}
	else {y = i;split(ls[i],k,x,ls[i]);pushup(y);}
}

int merge(int x,int y)
{
	if(!x || !y) return x|y;
	LL rd = rnd()%(siz[x]+siz[y]),rot;
	if(rd < siz[x]) {down(x);copy(rot = ++cnt,x);rs[rot] = merge(rs[rot],y);pushup(rot);return rot;}
	else {down(y);copy(rot = ++cnt,y);ls[rot] = merge(x,ls[rot]);pushup(rot);return rot;}
}

int Q(int k,int i)
{
	if(laz[i]) down(i);
	if(siz[ls[i]]+1 == k) return s[i];
	if(siz[ls[i]] < k) return Q(k-siz[ls[i]]-1,rs[i]);
	else return Q(k,ls[i]);
}

int main()
{
	int n,m;cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> a[i].c >> a[i].q;
	sort(a+1,a+n+1,cmp);
	rt[n+1] = cnt = 1;siz[1] = 1;
	for (int i = 1;i <= 30;i++)
		rt[n+1] = merge(rt[n+1],rt[n+1]);
	for (int i = n;i >= 1;i--)
	{
		int x,y;split(rt[i+1],a[i].c,x,y);
		copy(++cnt,rt[i+1]);laz[cnt]++,s[cnt]++;
		rt[i] = merge(x,cnt);
	}
	cin >> m;
	for (int i = 1,x;i <= m;i++)
		cin >> x,cout << Q(x+1,rt[1]) << ' ';
	return 0;
}
2024/5/14 09:14
加载中...