【BZOJ5293】【BJOI2018】—求和

传送门

考场有人做不起???

虽然 n a i i v e naiive 的我一眼50颗线段树+树剖…

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	char ch=getchar();
	int res=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
	return res;
}
const int N=300005;
const int K=55;
const int mod=998244353;
int f[N][K],n,m,cnt,k;
int adj[N],nxt[N<<1],to[N<<1],dep[N],fa[N],son[N],siz[N],top[N];
inline void addedge(int u,int v){
	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
}
inline int ksm(int a,int b,int res=1){
	for(;b;b>>=1,a=a*a%mod){
		if(b&1)res=res*a%mod;
	}
	return res;
}
void dfs1(int u){
	siz[u]=1;
	for(int i=1;i<=50;i++)
		f[u][i]=(f[fa[u]][i]+ksm(dep[u],i))%mod;
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u])continue;
		fa[v]=u,dep[v]=dep[u]+1;
		dfs1(v),siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp;
	if(son[u])dfs2(son[u],tp);
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
inline int Lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]>dep[v]?v:u;
}
signed main(){
	n=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		addedge(v,u),addedge(u,v);
	}
	dfs1(1),dfs2(1,1);
	m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),k=read();
		int lca=Lca(u,v);
		cout<<((f[u][k]+f[v][k]-f[lca][k]-f[fa[lca]][k])%mod+mod)%mod<<'\n';
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/88198094