ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 模板

2021-08-21 06:31:53  阅读:197  来源: 互联网

标签:int 题解 son fa siz rot 模板 define


传送门

前70pts巨水,
不过没有数据范围就可以为所欲为吗。。。
颜色是负数是几个意思。。。
以后见到这类不给数据范围的题先离散化

发现每个节点的操作都会向上影响到根节点
貌似可以启发式合并一路维护上去
考虑如何处理这个每个节点只能放 \(k\) 个球的限制
在每个节点维护一棵splay,以时间为下标,存这个时刻放入的小球颜色及是否对答案产生贡献
(每种颜色第一次出现的小球贡献为1,其余为0)
然后每个节点再开一个map记录这个节点每种颜色第一次出现的时间就好
每次插入如果比这个时间早就找到原来的点把贡献改成0

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long 
#define fir first
#define sec second
#define make make_pair
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, q;
int head[N], size, k[N], uni[N], usize, qx[N], qc[N], ans[N], siz2[N], msiz[N], mson[N];
struct edge{int to, next;}e[N<<1];
inline void add(int s, int t) {e[++size].to=t; e[size].next=head[s]; head[s]=size;}

int tot, rab[N<<3], rtop;
int siz[N<<3], col[N<<3], tim[N<<3], val[N<<3], sum[N<<3], son[N<<3][2], fa[N<<3];
#define siz(p) siz[p]
#define col(p) col[p]
#define tim(p) tim[p]
#define val(p) val[p]
#define sum(p) sum[p]
#define son(a, b) son[a][b]
#define fa(p) fa[p]
#define loc(p) (son(fa(p), 1)==p)
#define tran(a, x) son(a, (x)>tim(a))
#define pushup(p) 	sum(p)=sum(son(p, 0))+sum(son(p, 1))+val(p);\
					siz(p)=siz(son(p, 0))+siz(son(p, 1))+1
struct Splay{
	int rot;
	unordered_map< int, pair<int, int> > mp;
	Splay():rot(0){ins(-INF, -1, 0); ins(INF, -1, 0);}
	void ror(int x) {
		int y=fa(x), z=fa(y), k=loc(x);
		son(z, loc(y))=x; fa(x)=z;
		son(y, k)=son(x, k^1); fa(son(x, k^1))=y;
		son(x, k^1)=y; fa(y)=x;
		pushup(y); pushup(x);
	}
	void splay(int x, int pos) {
		int y, z;
		while (fa(x)!=pos) {
			y=fa(x), z=fa(y);
			if (z!=pos) loc(x)^loc(y)?ror(x):ror(y);
			ror(x);
		}
		if (!pos) rot=x;
	}
	void ins(int t, int c, int d) {
		//if (c!=-1) cout<<"ins: "<<t<<' '<<c<<' '<<d<<endl;
		if (d && mp.find(c)!=mp.end()) {
			pair<int, int> tem=mp[c];
			if (tem.fir<t) d=0;
			else {
				val(tem.sec)=0;
				splay(tem.sec, 0);
			}
		}
		int u=rot, f=0;
		while (u) f=u, u=tran(u, t);
		//u=(rtop?rab[rtop--]:++tot);
		u=++tot;
		siz(u)=1; col(u)=c; tim(u)=t;
		val(u)=sum(u)=d;
		if (f) tran(f, t)=u;
		if (d) mp[c]=make(t, u);
		son(u, 0)=son(u, 1)=0; fa(u)=f;
		splay(u, 0);
		//if (c!=-1) cout<<"u: "<<u<<' '<<val(u)<<' '<<sum(u)<<endl;
	}
	void find(int x) {
		int u=rot;
		while (u&&tran(u, x)) u=tran(u, x);
		splay(u, 0);
	}
	int rk(int x) {
		//cout<<"rk: "<<x<<' '<<siz(rot)<<endl;
		int u=rot, v;
		if (x>=siz(u)) return sum(u);
		while (1) {
			v=son(u, 0);
			if (x<=siz(v)) u=v;
			else if (x>siz(v)+1) u=son(u, 1), x-=siz(v)+1;
			else {splay(u, 0); return sum(son(u, 0));}
		}
	}
	void merge(int u, Splay& a) {
		//cout<<"merge "<<u<<' '<<tim(u)<<' '<<col(u)<<endl;
		if (son(u, 0)) merge(son(u, 0), a);
		if (son(u, 1)) merge(son(u, 1), a);
		if (col(u)!=-1) a.ins(tim(u), col(u), 1);
		rab[++rtop]=u;
	}
}rot[N];

void dfs(int u, int fa) {
	//cout<<"dfs "<<u<<' '<<fa<<endl;
	msiz[u]=siz2[u]=siz(rot[u].rot)-2; mson[u]=u;
	for (int i=head[u],v; ~i; i=e[i].next) {
		v = e[i].to;
		if (v==fa) continue;
		dfs(v, u);
		siz2[u]+=siz(rot[v].rot)-2;
		if (siz(rot[v].rot)-2>msiz[u])
			msiz[u]=siz(rot[v].rot)-2, mson[u]=v;
	}
	//cout<<"mson: "<<mson[u]<<endl;
	swap(rot[u], rot[mson[u]]);
	//cout<<"swap "<<u<<endl;
	for (int i=head[u],v; ~i; i=e[i].next) {
		v = e[i].to;
		if (v==fa) continue;
		//cout<<"goto merge "<<u<<' '<<v<<endl;
		rot[v].merge(rot[v].rot, rot[u]);
		//cout<<"return merge"<<endl;
	}
	ans[u]=rot[u].rk(k[u]+2);
	//cout<<"return "<<u<<endl;
}

signed main()
{
	memset(head, -1, sizeof(head));
	n=read();
	for (int i=1,u,v; i<n; ++i) {
		u=read(); v=read();
		add(u, v); add(v, u);
	}
	for (int i=1; i<=n; ++i) k[i]=read();
	m=read();
	for (int i=1; i<=m; ++i) qx[i]=read(), qc[i]=read(), uni[i]=qc[i];
	//cout<<"qc: "; for (int i=1; i<=m; ++i) cout<<qc[i]<<' '; cout<<endl;
	sort(uni+1, uni+m+1);
	usize=unique(uni+1, uni+m+1)-uni-1;
	for (int i=1; i<=m; ++i) qc[i]=lower_bound(uni+1, uni+usize+1, qc[i])-uni;
	//cout<<"qc: "; for (int i=1; i<=m; ++i) cout<<qc[i]<<' '; cout<<endl;
	for (int i=1; i<=m; ++i) rot[qx[i]].ins(i, qc[i], 1); //, cout<<"qins"<<endl;
	dfs(1, 0);
	q=read();
	for (int i=1; i<=q; ++i) printf("%d\n", ans[read()]);
	
	return 0;
}

标签:int,题解,son,fa,siz,rot,模板,define
来源: https://www.cnblogs.com/narration/p/15168748.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有