75pts 被卡常求助
查看原帖
75pts 被卡常求助
979266
Genius_Star楼主2024/4/13 11:52

求大佬帮忙康康,本地随机数据均 < 2s,洛谷最后 5 个点全 T。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
const ll N=200001,M=sqrt(N)+10,INF=1e18;
inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
          f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*f;
}
inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9)
	  write(x/10);
	putchar(x%10+'0');
}
struct Node{
	int op;
	int l,r;
}Q[N];
ll Min;
int n,m,rt,k,h,op,l,r,y,tag,cnt;
ll dep[N],ans[N];
int a[N],b[N],fa[N],dfn[N],id[N],d[N],p[N],z[N],t[N];
int A[N],L[M],R[M];
vector<pair<int,int>> E[N];
bool f[N];
class List{
public:
	bool F[N];
	int A[N];
	int cnt;
	inline void init(){
		cnt=0;
	}
	inline void insert(register int x){
		A[++cnt]=x;
		F[x]=1;
	}
	inline void dfs(register ll &Min){
		register int x=0;
		for(register int i=1;i<=cnt;i++){
			a[A[i]]=fa[a[A[i]]];
			Min=min(Min,dep[a[A[i]]]);
			b[A[i]]++;
			if(f[a[A[i]]])
			  F[A[i]]=0;
			else
			  A[++x]=A[i];
		}
		cnt=x;
	}
}ST;
inline void add(register int u,register int v,register int w){
	E[u].push_back({v,w});
	E[v].push_back({u,w});
}
inline void dfs1(register int u,register int f){
	p[u]=1,fa[u]=f;
	for(register auto t:E[u]){
		register int v=t.first,w=t.second;
		if(v==f)
		  continue;
		dep[v]=dep[u]+w;
		d[v]=d[u]+1;
		dfs1(v,u);
		p[u]+=p[v];
		if(p[v]>p[z[u]])
		  z[u]=v;
	}
}
inline void dfs2(register int u,register int k){
	dfn[u]=++cnt;
	id[cnt]=u;
	t[u]=k;
	if(!z[u])
	  return ;
	dfs2(z[u],k);
	for(register auto t:E[u]){
		register int v=t.first;
		if(v==fa[u]||v==z[u])
		  continue;
		dfs2(v,v);
	}
}
inline int get_fa(register int x,register int k){
	if(k>=d[x])
	  return rt;
	while(k>dfn[x]-dfn[t[x]]){
		k-=dfn[x]-dfn[t[x]]+1;
		x=fa[t[x]];
	}
	return id[dfn[x]-k];
}
inline void build(register int x){
	for(register int i=1;i<=n;i++)
	  f[i]=0; 
	ST.init();
	Min=INF,tag=0;
	for(register int i=L[x];i<=R[x];i++){
		ST.insert(i);
		f[a[i]]=1;
		Min=min(Min,dep[a[i]]);
	}
}
inline void solve(register int x){
	for(register int i=1;i<=m;i++){
		if(Q[i].r<L[x]||Q[i].l>R[x])
		  continue;
		l=max(L[x],Q[i].l),r=min(R[x],Q[i].r);
		if(Q[i].op==1){
			if(l==L[x]&&r==R[x]){
				tag++;
				ST.dfs(Min);				
			}
			else{
				for(register int j=l;j<=r;j++){
					a[j]=get_fa(a[j],tag-b[j]+1);
					if(!f[a[j]]){
						f[a[j]]=1;
						if(!ST.F[j])
						  ST.insert(j);
					}
					Min=min(Min,dep[a[j]]);
					b[j]=tag;
				}
			}
		}
		else{
			if(l==L[x]&&r==R[x])
			  ans[i]=min(ans[i],Min);
			else{
				for(register int j=l;j<=r;j++){
					a[j]=get_fa(a[j],tag-b[j]);
					ans[i]=min(ans[i],dep[a[j]]);
					b[j]=tag;
				}
			}
		}
	}
}
signed main(){
//	freopen("A.in","r",stdin);
//	freopen("A.out","w",stdout);
	n=read(),m=read(),rt=read();
	k=600,h=(n+k-1)/k;
	for(register int i=1;i<=h;i++){
		L[i]=(i-1)*k+1;
		R[i]=i*k;
	}
	R[h]=n;
	for(register int i=1;i<=n;i++)
	  A[i]=(i-1)/k+1;
	for(register int u,v,w,i=1;i<n;i++){
		u=read(),v=read(),w=read();
		add(u,v,w);
	}
	for(register int i=1;i<=n;i++)
	  a[i]=read();
	dfs1(rt,rt);
	dfs2(rt,rt);
	for(register int i=1;i<=m;i++){
		Q[i]={(int)read(),(int)read(),(int)read()};
		ans[i]=INF;
	}
	for(register int i=1;i<=h;i++){
		build(i);
		solve(i);
	}
	for(register int i=1;i<=m;i++){
		if(ans[i]!=INF){
			write(ans[i]);
			putchar('\n');
		}
	} 
	return 0;
}
2024/4/13 11:52
加载中...