日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P5643-[PKUWC2018]随机游走【min-max容斥,dp】

發布時間:2023/12/3 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P5643-[PKUWC2018]随机游走【min-max容斥,dp】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P5643


題目大意

給出nnn個點的一棵樹,一個人從點xxx開始隨機游走,然后QQQ次詢問給出一個點集SSS,求期望多少步這個人會經過這個點集中的所有點。

1≤n≤18,1≤Q≤50001\leq n\leq 18,1\leq Q\leq 50001n18,1Q5000


解題思路

整個點集都走完比較難統計,我們可以考慮用min?maxmin-maxmin?max容斥轉為求走到其中一個點的期望步數。

我們設我們目前枚舉的集合是SSS,那么首先有fx=0(x∈S)f_x=0(x\in S)fx?=0(xS)

然后有轉移方程:
fx=1degx(ffax+∑x→yfy)f_{x}=\frac{1}{deg_x}(f_{fa_x}+\sum_{x\rightarrow y}f_{y})fx?=degx?1?(ffax??+xy?fy?)
慣例的我們設fx=Axffax+Bxf_x=A_xf_{fa_x}+B_xfx?=Ax?ffax??+Bx?
fx=1degx(ffax+∑x→y(Ayfx+By))f_{x}=\frac{1}{deg_x}\left(f_{fa_x}+\sum_{x\rightarrow y}(A_yf_x+B_y)\right)fx?=degx?1?(ffax??+xy?(Ay?fx?+By?))
fx=1degxffax+sumAfxdeg+1degxsumB+1f_{x}=\frac{1}{deg_x}f_{fa_x}+\frac{sumAf_x}{deg}+\frac{1}{deg_x}sumB+1fx?=degx?1?ffax??+degsumAfx??+degx?1?sumB+1
degx?sumAdegxfx=1degxffax+1degxsumB+1\frac{deg_x-sumA}{deg_x}f_x=\frac{1}{deg_x}f_{fa_x}+\frac{1}{deg_x}sumB+1degx?degx??sumA?fx?=degx?1?ffax??+degx?1?sumB+1
fx=1degx?sumAffax+degx+sumBdegx?sumAf_x=\frac{1}{deg_x-sumA}f_{fa_x}+\frac{deg_x+sumB}{deg_x-sum_A}fx?=degx??sumA1?ffax??+degx??sumA?degx?+sumB?

這樣我們就可以推出AAABBB,而BxB_xBx?就是節點xxxfff值,記gS=Bxg_S=B_xgS?=Bx?

那么根據min-max容斥如果我們詢問集合SSS時答案就是
∑T?S(?1)∣T∣+1gT\sum_{T\sube S}(-1)^{|T|+1}g_TT?S?(?1)T+1gT?

用個高維前綴和就可以預處理所有集合的答案了。

時間復雜度:O(n2nlog?P)O(n2^n\log P)O(n2nlogP)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=18,P=998244353; struct node{ll to,next; }a[N<<1]; ll n,Q,rt,tot,ls[N],deg[N]; ll A[N],B[N],c[1<<N],f[1<<N]; ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans; } void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;deg[y]++;return; } void dfs(ll x,ll fa,ll S){ll sumA=0,sumB=0;if((S>>x)&1){A[x]=B[x]=0;return;}for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x,S);sumA=(sumA+A[y])%P;sumB=(sumB+B[y])%P;}ll inv=power((deg[x]-sumA+P)%P,P-2);A[x]=inv;B[x]=(deg[x]+sumB)*inv%P;return; } signed main() {scanf("%lld%lld%lld",&n,&Q,&rt);rt--;for(ll i=1,x,y;i<n;i++){scanf("%lld%lld",&x,&y);x--;y--;addl(x,y);addl(y,x);}ll MS=(1<<n);for(ll s=1;s<MS;s++){memset(A,0,sizeof(A));memset(B,0,sizeof(B));dfs(rt,n,s);f[s]=B[rt];}for(ll s=1;s<MS;s++){c[s]=c[s-(s&-s)]+1;f[s]=((c[s]&1)?f[s]:(P-f[s]));}for(ll i=0;i<n;i++)for(ll s=MS-1;s>=0;s--)if((s>>i)&1)(f[s]+=f[s-(1<<i)])%=P;while(Q--){ll k,s=0;scanf("%lld",&k);for(ll i=0,x;i<k;i++)scanf("%lld",&x),s|=(1<<x-1);printf("%lld\n",f[s]);}return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的P5643-[PKUWC2018]随机游走【min-max容斥,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。