求助萌新第一天学c艹 95pts WA #21
  • 板块CF487E Tourists
  • 楼主Skadi_H
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/1/25 21:19
  • 上次更新2024/1/26 08:05:58
查看原帖
求助萌新第一天学c艹 95pts WA #21
1006027
Skadi_H楼主2024/1/25 21:19

思路是圆方树+树链剖分(线段树)+LCA。

另外,蒟蒻码力实在是太弱了,写稍微码量大一点的题就会寄QaQ。求大佬们提供码力提升题单,感激不尽!

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
struct stree
{
	int l,r,val;
}t[800005];
struct edge
{
	int v,nxt;
}e[200005],re[200005];
int n,m,u,v,q,pos,rpos,cnt,idx;
int a[200005],head[100005],rhead[200005],dfn[200005],low[200005];
int dep[200005],siz[200005],fa[200005],son[200005],/**/p[200005],top[200005];
int st[200005][21];
bool vis[200005];
char con;
stack<int>s;
multiset<int>ms[200005];
void addedge(int u,int v)
{
	if(u==v)
		return;
	e[++pos]={v,head[u]};
	head[u]=pos;
}
void raddedge(int u,int v)
{
	if(u==v)
		return;
	re[++rpos]={v,rhead[u]};
	rhead[u]=rpos;
}
//yuanfangtree
void tarjan(int u)
{
	dfn[u]=low[u]=++idx;
	s.push(u);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(low[v]==dfn[u])
			{
				cnt++;
				int lin=0;
				while(s.size()&&lin!=v)
				{
					lin=s.top();
					s.pop();
					raddedge(lin,cnt);
					raddedge(cnt,lin);
				}
				raddedge(u,cnt);
				raddedge(cnt,u);
			}
		}
		else
			low[u]=min(low[u],dfn[v]);
	}
}
//pre
void dfs1(int u,int f=0)
{
	dep[u]=dep[f]+1;
	siz[u]=1;
	fa[u]=f;
	int maxson=0;
	for(int i=rhead[u];i;i=re[i].nxt)
	{
		int v=re[i].v;
		if(v==f)
			continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>maxson)
		{
			maxson=siz[v];
			son[u]=v;
		}
	}
}
void dfs2(int u,int t)
{
	dfn[u]=++idx;
	p[idx]=u;
	top[u]=t;
	if(!son[u])
		return;
	dfs2(son[u],t);
	for(int i=rhead[u];i;i=re[i].nxt)
	{
		int v=re[i].v;
		if(v==fa[u]||v==son[u])
			continue;
		dfs2(v,v);
	}
}
//stree
void pushup(int idx)
{
	t[idx].val=min(t[2*idx].val,t[2*idx+1].val);
}
void build(int idx,int l,int r)
{
	t[idx].l=l,t[idx].r=r;
	if(l==r)
	{
		t[idx].val=a[p[l]];
		return;
	}
	int mid=l+r>>1;
	build(2*idx,l,mid);
	build(2*idx+1,mid+1,r);
	pushup(idx);
}
void update(int idx,int pos,int val)
{
	if(t[idx].l>pos||t[idx].r<pos)
		return;
	if(t[idx].l==t[idx].r)
	{
		t[idx].val=val;
		return;
	}
	int mid=t[idx].l+t[idx].r>>1;
	if(pos<=mid)
		update(2*idx,pos,val);
	else
		update(2*idx+1,pos,val);
	pushup(idx);
}
int query(int idx,int l,int r)
{
	if(t[idx].l>r||t[idx].r<l)
		return mod;
	if(l<=t[idx].l&&t[idx].r<=r)
		return t[idx].val;
	int mid=t[idx].l+t[idx].r>>1;
	int cnt=mod;
	if(l<=mid)
		cnt=min(cnt,query(2*idx,l,r));
	if(mid+1<=r)
		cnt=min(cnt,query(2*idx+1,l,r));
	return cnt;
}
int querypath(int u,int v)
{
	int cnt=mod;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])
			swap(u,v);
		cnt=min(cnt,query(1,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])
		swap(u,v);
	cnt=min(cnt,query(1,dfn[u],dfn[v]));
	return cnt;
}
//LCA
void dfs(int u,int f=0)
{
	st[u][0]=f;
	//dep[u]=dep[f]+1;
	for(int i=1;i<=__lg(dep[u]);i++)
	{
		st[u][i]=st[st[u][i-1]][i-1];
	}
	for(int i=rhead[u];i;i=re[i].nxt)
	{
		int v=re[i].v;
		if(v==f)
			continue;
		dfs(v,u);
	}
}
int LCA(int u,int v)
{
	if(dep[u]<dep[v])
		swap(u,v);
	while(dep[u]!=dep[v])
	{
		u=st[u][__lg(dep[u]-dep[v])];
	}
	if(u==v)
		return u;
	for(int i=__lg(dep[u]);i>=0;i--)
	{
		if(st[u][i]!=st[v][i])
		{
			u=st[u][i];
			v=st[v][i];
		}
	}
	return st[u][0];
}
int main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>m>>q;
	cnt=n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=m;i++)
	{
		cin>>u>>v;
		addedge(u,v);
		addedge(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			tarjan(i);
			s.pop();
		}
	}
	idx=0;
	dfs1(1);
	dfs2(1,1);
	for(int i=n+1;i<=cnt;i++)
	{
		a[i]=mod;
		for(int j=rhead[i];j;j=re[j].nxt)
		{
			int v=re[j].v;
			if(v==fa[i])
				continue;
			ms[i].insert(a[v]);
		}
		a[i]=*ms[i].begin();
	}
	build(1,1,cnt);
	dfs(1);
	while(q--)
	{
		cin>>con;
		if(con=='C')
		{
			int pos,val;
			cin>>pos>>val;
			if(fa[pos]>n)
			{
				int f=fa[pos];
				ms[f].erase(ms[f].find(a[pos]));
				ms[f].insert(val);
				update(1,dfn[f],*ms[f].begin());
			}
			a[pos]=val;
			update(1,dfn[pos],val);
		}
		else
		{
			int u,v;
			cin>>u>>v;
			int ans=querypath(u,v),lca=LCA(u,v);
			if(lca>n)
				ans=min(ans,a[fa[lca]]);
			cout<<ans<<endl;
		}
	} 
	return 0;
}
//Skadi_H
2024/1/25 21:19
加载中...