Bribes

題目鏈接:Bribes


顯然,樹上差分,分別維護上下路徑,然後對當前路徑討論正反即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N*2,mod=1e9+7;
int n,m,s[N*10],sz[N],bl[N],pos[N],dep[N],f[N],son[N],cnt,p1[N],p2[N],mi[N*10]={1},res;
int head[N],nex[M],to[M],w[M],tot;
inline void add(int a,int b,int c){to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;}
void dfs1(int x){
	sz[x]=1;
	for(int i=head[x];i;i=nex[i])	if(to[i]!=f[x]){
		f[to[i]]=x;	dep[to[i]]=dep[x]+1;
		dfs1(to[i]);	sz[x]+=sz[to[i]];
		if(sz[to[i]]>sz[son[x]])	son[x]=to[i];
	}
}
void dfs2(int x,int belong){
	pos[x]=++cnt;	bl[x]=belong;
	if(son[x])	dfs2(son[x],belong);
	for(int i=head[x];i;i=nex[i])	if(dep[to[i]]>dep[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
inline int lca(int x,int y){
	while(bl[x]!=bl[y]){
		if(dep[bl[x]]<dep[bl[y]])	swap(x,y);	x=f[bl[x]];
	}
	return dep[x]>dep[y]?y:x;
}
void dfs(int x,int fa){
	for(int i=head[x];i;i=nex[i])	if(to[i]!=fa){
		dfs(to[i],x);	p1[x]+=p1[to[i]],p2[x]+=p2[to[i]];
		if(w[i]==1)	res=(res+mi[p1[to[i]]]-1+mod)%mod;
		else if(w[i]==-1)	res=(res+mi[p2[to[i]]]-1+mod)%mod;
	}
}
signed main(){
	cin>>n;
	for(int i=1,a,b,c;i<n;i++)	scanf("%lld %lld %lld",&a,&b,&c),add(a,b,c),add(b,a,-c);
	cin>>m; s[0]=1;
	for(int i=1;i<=m;i++)	scanf("%lld",&s[i]),mi[i]=mi[i-1]*2%mod;
	dfs1(1);	dfs2(1,1);
	for(int i=1,l;i<=m;i++){
		l=lca(s[i],s[i-1]);
		p1[s[i-1]]++,p1[l]--,p2[s[i]]++,p2[l]--;
	}
	dfs(1,1);
	cout<<res;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章