D. Graph and Queries (并查集+线段树)

题目链接:http://codeforces.com/contest/1416/problem/D

 

应该是图上的比较经典的问题了(然而我不会

用并查集把图区间化,思想是根据删除顺序的倒叙来建树,最后dfs序即可,然后用线段树维护答案

 

代码:

#include
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair pii;
const int MAXN=5e5+5;
const int MAXM=3e5+5;
const int MAXQ=5e5+5;
vector E[MAXN];
int n,m,q;
pii e[MAXM],mdf[MAXQ];
int p[MAXN],in[MAXN],out[MAXN];
bool vis[MAXM];
int tim=0;
struct DSU
{
	int fa[MAXN];
	void init(int n)
	{
		for(int i=1;i<=n;i++)
			fa[i]=i;
	}
	int find(int x)
	{
		if(x^fa[x]) return fa[x]=find(fa[x]);
		return x;
	}
	void merge(int x,int y)
	{
		x=find(x);
		y=find(y);
		if(x==y) return ;
		++n;
		fa[n]=n;fa[x]=n;fa[y]=n;
		E[n].pb(x);E[n].pb(y);
	}
}dsu;
struct seg
{
	#define lson l,mid,rt<<1
	#define rson mid+1,r,rt<<1|1
	pii mx[MAXN<<2];
	inline void push_up(int rt)
	{
		mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
	}
	void update(int pos,pii val,int l,int r,int rt)
	{
		if(l==r)
		{
			mx[rt]=val;
			return ;
		}
		int mid=(l+r)>>1;
		if(pos<=mid)
			update(pos,val,lson);
		if(mid>1;
		pii ret(0,0);
		if(L<=mid)
			ret=max(ret,query(L,R,lson));
		if(mid=1;i--)
	{
		if(mdf[i].xx==1)
		{
			mdf[i].yy=dsu.find(mdf[i].yy);
		}
		else
		{
			int id=mdf[i].yy;
			dsu.merge(e[id].xx,e[id].yy);
		}
	}
	for(int i=1;i<=n;i++)
		if(dsu.find(i)==i)
			dfs(i,0);
	for(int i=1;i<=n;i++)
		se.update(in[i],{p[i],in[i]},1,n,1);
	for(int i=1;i<=q;i++)
	{
		if(mdf[i].xx==1)
		{
			int id=mdf[i].yy;
			pii res=se.query(in[id],out[id],1,n,1);
			printf("%d\n",res.xx);
			if(res.yy)
				se.update(res.yy,{0,0},1,n,1);
		}
	}
	return 0;
}

 

你可能感兴趣的:(codeforces)