• 欢迎光临~

2022/10/18 总结

开发技术 开发技术 2022-10-19 次浏览

反转 DAG

  • 考场暴力搜索加玄学优化得到 (mathtt{54pts}) (虽然翌日在语文课上反思了一下想起了还有可以加的优化……)

Solution

  • 二分答案,枚举每次最大的 (k),然后把原图中所有边权 (le k) 的边都删掉,再跑一遍原图,看是不是 (DAG)
AC code
#include<bits/stdc++.h>
using namespace std;

inline int read(){
	int s=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-1;
		ch=getchar();
	} 
	while(isdigit(ch)){
		s=s*10+int(ch-'0');
		ch=getchar();
	}
	return s*f;
}

const int N=1e5+10;

int n,q,rt;
int l[N],r[N],ind[N],id[N],v[N],cnt=0;
int head[N],ver[N],nxt[N],tot=0;
int f[25][N],dep[N];

struct memr{
	int l,r;
	int mn;
}tr[N<<3];

void add(int x,int y){
	ver[++tot]=y;
	nxt[tot]=head[x],head[x]=tot;
	return ;
}

int LCA(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=24;i>-1;--i)
		if(dep[f[i][x]]>=dep[y])
			x=f[i][x];
	if(x==y) return x;
	return 0;
}

int A(int x,int h){
	for(int i=24;i>-1;--i)
		if(dep[f[i][x]]>=h)
			x=f[i][x];
	return x;
}

void dfs(int p){
	ind[++cnt]=p;
	id[p]=cnt;
	l[p]=cnt;
	dep[p]=dep[f[0][p]]+1;
	for(int i=1;i<25 && f[i-1][p];++i)
		f[i][p]=f[i-1][f[i-1][p]];
	for(int i=head[p];i;i=nxt[i])
		dfs(ver[i]);
	r[p]=cnt;
	return ;
}

void pushup(int p){
	tr[p].mn=min(tr[p<<1].mn,tr[p<<1|1].mn);
	return ;
}

void mix(int p,int x,int v){
	if(x==tr[p].l && tr[p].r==x){
		tr[p].mn=v;
		return ;
	}
	int mid=(tr[p].l+tr[p].r)>>1;
	if(x<=mid) mix(p<<1,x,v);
	else mix(p<<1|1,x,v);
	pushup(p);
	return ;
}

int ask(int p,int l,int r){
	if(l<=tr[p].l && tr[p].r<=r)
		return tr[p].mn;
	int cnt=0x3f3f3f3f;
	int mid=(tr[p].l+tr[p].r)>>1;
	if(l<=mid) cnt=min(cnt,ask(p<<1,l,r));
	if(mid<r) cnt=min(cnt,ask(p<<1|1,l,r));
	return cnt;
}

void build(int p,int l,int r){
	tr[p].l=l,tr[p].r=r;
	if(l==r){
		tr[p].mn=v[ind[l]];
		return ;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
	return ;
}

int main(){
//	freopen("tree.in","r",stdin);
//	freopen("tree.out","w",stdout);
	n=read(),q=read();
	for(int i=1;i<=n;++i){
		f[0][i]=read(),v[i]=read();
		add(f[0][i],i);
	}
	rt=1;
	dfs(1);
	build(1,1,n);
	char opt;
	int x,y,ans;
	while(q--){
		cin>>opt;
		x=read();
		if(opt=='V'){
			y=read();
			mix(1,id[x],y);
		}
		else{
			if(opt=='E')
				rt=x;
			else{
				int a=LCA(rt,x);
				if(x==rt)
					ans=tr[1].mn;
				else if(a==x){
					int z=A(rt,dep[x]+1);
					ans=min(ask(1,1,l[z]-1),ask(1,r[z]+1,n));
				}
				else ans=ask(1,l[x],r[x]);
				printf("%dn",ans);
			}
		}
	}
	return 0;
}
程序员灯塔
转载请注明原文链接:2022/10/18 总结
喜欢 (0)
违法和不良信息举报电话:022-22558618 举报邮箱:dljd@tidljd.com