题目连接spa
\(Desccription\)
给定一棵树,John从任意一个点开始,每次走向一个未到达过的点。每一个点均可以有或没有赌场,每通过一个赌场心情都会反转,旅行开始前心情很好。
问有多少种方案使得旅行结束后心情很好。code
\(n≤10^5\)ip
\(Solution\)
把题目抽象一下:
每一个点随机一个\(0/1\)的权值,随机选择一个点做为根,有多少种方案使得根节点到全部叶节点路径上的异或和为\(0\)。get
发现叶节点到根的路径的权值异或和能够由叶节点肯定。记叶节点数为\(tot\)。
1.若所选的根节点不是叶节点,那么除叶节点外的\(n-tot\)个点的权值能够随便选,方案数为\((n-tot)\times 2^{n-tot}\)。
2.若所选的根节点是叶节点,那么除其余\(n-tot-1\)个叶节点外的全部的点权值能够随便选,方案数为\(tot\times 2^{n-tot+1}\)io
\(ans=(n-tot)\times 2^{n-tot}+tot\times 2^{n-tot+1}=(n+tot)\times 2^{n-tot}\)class
#include<complex> #include<cstdio> using namespace std; const int mod=1e9+7; const int N=1e5+7; int n,tot; int in[N]; int qread() { int x=0; char ch=getchar(); while(ch<'0' || ch>'9')ch=getchar(); while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } long long Fpow(long long b,int p) { long long res=1; for(;p;p>>=1,b=b*b%mod) if(p&1)res=res*b%mod; return res; } int main() { scanf("%d",&n); for(int i=1;i<n;i++) in[qread()]++,in[qread()]++; for(int i=1;i<=n;i++) if(in[i]==1)tot++; printf("%d\n",(n+tot)*Fpow(2,n-tot)%mod); return 0; }