带修莫队 + 平衡树CE?
查看原帖
带修莫队 + 平衡树CE?
701221
Chr0n1CleC楼主2022/9/3 14:16
#include<stdio.h>
#define N 100009
#include<algorithm>
#include<math.h>
using namespace std;

int block;

struct query
{
	int l, r, p, k, t;
}q[N];

int cntq;

int a[N];

struct modife
{
	int x, y;
}mo[N];

int cntmo;

struct Splay
{
	int rt, tot, cnt[N], val[N], fa[N], ch[N][2], siz[N];
	inline void updata(int x)
	{
		siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
	}
	inline bool get(int x)
	{
		return x == ch[fa[x]][1];
	}
	inline void clear(int x)
	{
		cnt[x] = val[x] = fa[x] = ch[x][0] = ch[x][1] = siz[x] = 0;
	}
	inline void rorate(int x)
	{
		int y = fa[x], z = fa[y], f = get(x);
		ch[y][f] = ch[x][!f];
		if (ch[x][!f])
			fa[ch[x][!f]] = y;
		ch[x][!f] = y;
		fa[y] = x;
		fa[x] = z; 
		if (z)
			ch[z][y == ch[z][1]] = x;
		updata(x), updata(y);
	}
	inline void splay(int x, int root = 0)
	{
		while (fa[x] != root)
		{
			//			if (get(x) == get(fa[x]))//三点共线 
			//				rorate(fa[x]);//先旋转父节点 
			rorate(x);//再旋转子节点 
		}
		if (!root)
			rt = x;//如果时旋转到根,那么根就是 x了 
	}
	inline void insert(int x)
	{
		if (!rt)
		{
			rt = ++ tot;
			val[tot] = x;
			cnt[tot] = 1;//构建新点 
			updata(rt);
			return;
		}//树都没有 
		int cur = rt, f = 0;
		while (1)
		{
			if (val[cur] == x)
			{
				cnt[cur] ++;
				updata(cur);
				updata(f);
				splay(cur);
				return;
			}//重复 
			f = cur;
			cur = ch[cur][val[cur] < x];
			if (!cur)
			{
				ch[f][val[f] < x] = ++ tot;//构建关系 
				fa[tot] = f;//构建关系 
				val[tot] = x;
				cnt[tot] = 1;
				updata(tot);
				updata(f);
				splay(tot);//规定操作完都得splay上去
				return;
			}//到了地方了 
		}
	}
	inline int nxt()
	{
		int cur = ch[rt][1];
		if (!cur)
			return cur;
		while (ch[cur][0])//一直跳 
			cur = ch[cur][0];
		splay(cur);
		return cur;
	}
	inline int pre()
	{
		int cur = ch[rt][0];
		if (!cur)
			return cur;
		while (ch[cur][1])
			cur = ch[cur][1];
		splay(cur);
		return cur; 
	}//同理 
	inline int rank(int x)
	{
		int cur = rt, ret = 0;
		while (cur)
		{
			if (x < val[cur])
				cur = ch[cur][0];
			else
			{
				ret += siz[ch[cur][0]];
				if (x == val[cur])
				{
					splay(cur);
					return ret + 1;
				}
				ret += cnt[cur];
				cur = ch[cur][1];
			}
		}
	}//查找x的排名 
	inline void del(int x)
	{
		rank(x);
		if (cnt[rt] > 1)
		{
			cnt[rt] --, siz[rt] --;
			return;
		}
		if (!ch[rt][0] && !ch[rt][1])
		{
			clear(rt);
			rt = 0;
			return;
		}
		if (!ch[rt][0])
		{
			int cur = rt;
			rt = ch[rt][1];
			fa[rt] = 0;
			clear(cur);
			return;
		}
		if (!ch[rt][1])
		{
			int cur = rt;
			rt = ch[rt][0];
			fa[rt] = 0;
			clear(cur);
			return;
		}
		int cur = rt, k = pre();
		fa[ch[cur][1]] = k;
		ch[k][1] = ch[cur][1];
		clear(cur);
		updata(rt);
	}
	inline int xrank(int x)
	{
		int cur = rt;
		while (1)
		{
			if (ch[cur][0] && x <= siz[ch[cur][0]])
				cur = ch[cur][0];
			else
			{
				x -= siz[ch[cur][0]] + cnt[cur];
				if (x <= 0)
				{
					splay(cur);
					return val[cur];
				}
				cur = ch[cur][1];
			}
		}
	}//查找排名为x的数 
};

Splay T;

inline char getch()
{
	char ret = getchar();
	while (ret == ' ' || ret == '\n')
		ret = getchar();
	return ret;
}

inline bool cmp(query a, query b)
{
	return (a.l / block != b.l / block) ? a.l < b.l : a.r < b.r;
}

int ans[N];

inline void add(int pos)
{
	T.insert(a[pos]);
}

inline void del(int pos)
{
	T.del(a[pos]);
}

inline void modi(int pos)
{
	T.del(a[mo[pos].x]);
	T.insert(mo[pos].y);
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	block = sqrt(n);
	for (int i = 1;i <= n;++ i)
		scanf("%d", &a[i]);
	char opt;
	int l, r, k;
	for (int i = 1;i <= m;++ i)
	{
		opt = getch();
		scanf("%d%d", &l, &r);
		if (opt == 'Q')
			q[++ cntq].l = l, q[cntq].r = r, scanf("%d", &k), q[cntq].k = k, q[cntq].t = cntmo;
		else
			mo[++ cntmo].x = l, mo[cntmo].y = r;
	}
	sort(q + 1, q + 1 + cntq, cmp);
	int curL = 0, curR = 0, curT = 0;
	for (int i = 1;i <= cntq;i ++)
	{
		int L = q[i].l, R = q[i].r, T = q[i].t;
		while (curR < R)
			add(++ curR);
		while (curL > L)
			add(-- curL);
		while (curR > R)
			del(curR ++);
		while (curL < L)
			del(curL --);
		while (curT < T)
			modi(++ curT);
		while (curT > T)
			del(curT --);
		ans[q[i].p] = T.xrank(q[i].k);
	}
	for (int i = 1;i <= cntq;i ++)
		printf("%d\n", ans[i]);
	
	return 0;
}

错误信息: [错误] request for member 'xrank' in 'T', which is of non-class type 'int'

2022/9/3 14:16
加载中...