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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

LOJ#2542 随机游走

發布時間:2024/4/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LOJ#2542 随机游走 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

解:首先minmax容斥變成經過集合t的第一個點就停止的期望步數。對于某個t,設從x開始的期望步數為f(x)

如果x∈t,f(x) = 0。否則f(x) = ∑f(y) / in[x] + 1

樹上高斯消元。從葉子往上,可以發現每個點都可以表示為Af(fa) + B

于是我們推一波式子,參考,就可以對每個t,O(n)求出f(root)。

然后每個詢問就枚舉子集。

注意DFS的時候可以剪枝,遇到x∈t就返回,否則T飛.....

?

1 #include <bits/stdc++.h> 2 3 const int N = 30, MO = 998244353; 4 5 inline void read(int &x) { 6 x = 0; 7 char c = getchar(); 8 while(c < '0' || c > '9') c = getchar(); 9 while(c >= '0' && c <= '9') { 10 x = x * 10 + c - 48; 11 c = getchar(); 12 } 13 return; 14 } 15 16 struct Edge { 17 int nex, v; 18 }edge[N << 1]; int tp; 19 20 int n, rt, e[N], A[N], B[N], now, in[N], ans[1 << 19], cnt[1 << 19], ans2[1 << 19]; 21 22 inline int qpow(int a, int b) { 23 int ans = 1; 24 a = (a + MO) % MO; 25 while(b) { 26 if(b & 1) ans = 1ll * ans * a % MO; 27 a = 1ll * a * a % MO; 28 b = b >> 1; 29 } 30 return ans; 31 } 32 33 inline void add(int x, int y) { 34 tp++; 35 edge[tp].v = y; 36 edge[tp].nex = e[x]; 37 e[x] = tp; 38 return; 39 } 40 41 void DFS(int x, int f) { 42 if(((1 << (x - 1)) | now) == now) { 43 A[x] = B[x] = 0; 44 return; 45 } 46 int sa = 0, sb = 0; 47 for(int i = e[x]; i; i = edge[i].nex) { 48 int y = edge[i].v; 49 if(y == f) continue; 50 DFS(y, x); 51 sa = (sa + A[y]) % MO; 52 sb = (sb + B[y]) % MO; 53 } 54 55 A[x] = qpow(in[x] - sa, MO - 2); 56 B[x] = 1ll * A[x] * (in[x] + sb) % MO; 57 58 return; 59 } 60 61 int main() { 62 int q; 63 read(n); read(q); read(rt); 64 for(register int i = 1, x, y; i < n; i++) { 65 read(x); read(y); 66 add(x, y); add(y, x); 67 in[x]++; in[y]++; 68 } 69 70 int lm = 1 << n; 71 /*for(now = 1; now < lm; now++) { 72 //memset(A, ) 73 DFS(rt, 0); 74 ans[now] = B[rt]; 75 }*/ 76 memset(ans, -1, sizeof(ans)); 77 memset(ans2, -1, sizeof(ans2)); 78 79 for(register int i = 1; i < lm; i++) { 80 cnt[i] = 1 + cnt[i - (i & (-i))]; 81 } 82 83 /// prework OVER 84 for(register int i = 1, k; i <= q; i++) { 85 read(k); 86 int s = 0; 87 for(register int j = 1, x; j <= k; j++) { 88 read(x); 89 s |= (1 << (x - 1)); 90 } 91 int Ans = 0; 92 if(ans2[s] != -1) { 93 Ans = ans2[s]; 94 } 95 else { 96 for(register int t = s; t; t = (t - 1) & s) { 97 if(ans[t] == -1) { 98 now = t; 99 DFS(rt, 0); 100 ans[t] = B[rt]; 101 } 102 if(cnt[t] & 1) Ans = (Ans + ans[t]) % MO; 103 else Ans = (Ans - ans[t] + MO) % MO; 104 } 105 ans2[s] = Ans; 106 } 107 printf("%d\n", (Ans + MO) % MO); 108 } 109 110 return 0; 111 } AC代碼

?

轉載于:https://www.cnblogs.com/huyufeifei/p/10518598.html

總結

以上是生活随笔為你收集整理的LOJ#2542 随机游走的全部內容,希望文章能夠幫你解決所遇到的問題。

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