2020CCPC長春題解 I - Kawaii Courier

idyllic發表於2020-11-22

2020CCPC長春題解 I - Kawaii Courier

題目大意:給一個樹,讓你求每個節點走到根節點的期望的d*x^d,d為走過的邊個數。走法是每次隨機等概率走到相鄰的點。

題目分析: 相對於經典的距離d的期望,這裡要求的是d*x^d的期望。

      我們設F(a)=a *x^a

      考察F(a+b)與F(a) F(b)的關係,很遺憾,沒法直接表示。

      引入,輔助函式G(a)=x^a

      那麼F(a+b)=F(a)*G(b)+F(b)*G(a)

      而G(a+b)=G(a)*G(b)

      那麼分別用兩個DFS求出F,G。再用一個DFS得到答案即可。複雜度O(nlogn) n是dfs複雜度,log是逆元複雜度。
程式碼如下:

2020CCPC長春題解 I - Kawaii Courier
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const long long mod=1e9+7;
 4 const long long maxn=1e5+10;
 5 long long b[maxn],c[maxn],n,k,px,qx,nx,u,v,ans;
 6 vector<long long> a[2*maxn];
 7 long long ksm(long long x,long long t)
 8 {
 9     long long ans=1;
10     long long res=x;
11     while (t)
12     {
13         if (t&1) ans=ans*res%mod;
14         res=res*res%mod;
15         t=t>>1;
16     }
17     return ans;
18 }
19 long long _inv(long long x)
20 {
21     x=(x%mod+mod)%mod;
22     return ksm(x,mod-2);
23 }
24 void init()
25 {
26     scanf("%lld%lld%lld%lld",&n,&k,&px,&qx);
27     nx=(px*ksm(qx,mod-2))%mod;
28     for (int i=1;i<n;i++)
29     {
30         scanf("%lld%lld",&u,&v);
31         a[u].push_back(v);
32         a[v].push_back(u);
33     }
34 }
35 void dfs1(long long x,long long fa)
36 {
37     long long sum=0;
38     for (int i=0;i<a[x].size();i++)
39     {
40         if (a[x][i]==fa) continue;
41         dfs1(a[x][i],x);
42         sum=(sum+b[a[x][i]])%mod;
43     }
44     b[x]=(nx*_inv(a[x].size()-nx*sum%mod))%mod;
45 }
46 void dfs2(long long x,long long fa)
47 {
48     long long sum1=0,sum2=0;
49     for (int i=0;i<a[x].size();i++)
50     {
51         if (a[x][i]==fa) continue;
52         dfs2(a[x][i],x);
53         sum1=(sum1+b[a[x][i]])%mod;
54         sum2=(sum2+c[a[x][i]])%mod;
55     }
56     c[x]=((nx*b[x]%mod)*(sum1+sum2)%mod+nx)%mod;
57     c[x]=c[x]*_inv(a[x].size()-nx*sum1%mod)%mod;
58 }
59 void get_ans(long long x,long long fa,long long f,long long g)
60 {
61     if (x!=k)     ans=ans^(x*((f*c[x]+g*b[x])%mod)%mod);
62     for (int i=0;i<a[x].size();i++)
63     {
64         if (a[x][i]==fa) continue;
65         get_ans(a[x][i],x,f*b[x]%mod,(f*c[x]+g*b[x])%mod);
66     }
67 }
68 int main()
69 {
70     init();
71     dfs1(k,k);
72     dfs2(k,k);
73     b[k]=1;
74     c[k]=0;
75     ans=0;
76     get_ans(k,k,1,0);
77     printf("%lld\n",ans);
78     return 0;
79 }
View Code of I

 

相關文章