题目链接:
旅行的意义
Gym - 102174L
题目大意:
天天身在 11 号城市,他每到达一个旅游城市都会先花一天的时间游玩当地的旅游景点。接下来他也没有明确的目的地,所以第二天他会随机地选择该城市的一条直达线路,花费一天的时间通往下一个旅游城市。当然,如果这个城市的旅游景点太好玩的话,他可能会选择再逗留一天,但是由于假期有限,他在当前的旅游城市最多只能呆 22 天。例如,当天天在城市 CC 时,若城市 CC 有 22 条直达线路分别通往城市 AA 和城市 BB,则在第一天的游玩过后,第二天他有 1313 的可能会选择继续逗留在城市 CC 多游玩一天,但是第三天他一定不会再逗留在城市 CC 了;同时他有 1313 可能会选择立即搭乘直达城市 AA 的高铁;他也有 1313 的可能会选择立即搭乘直达城市 BB的高铁。
当天天把所有的旅游城市都游玩过后,他也就只能结束这段难忘的五一旅行假期了。现在请聪明的你帮天天提前计算一下,他本次旅行时间的期望是多少呢?
容易证明天天旅行时间的期望为 PQPQ 的形式,其中 PP 和 QQ 互质,且 Q≢0 (mod 998244353)Q≢0 (mod 998244353)。因此答案请以 P⋅Q−1 (mod 998244353)P⋅Q−1 (mod 998244353) 的形式输出,其中 Q−1Q−1 表示 QQ 在取模 998244353998244353 下的逆元。
具体思路:
dp[u][0]代表当前天天刚到达u这个城市并且玩了一天。
dp[u][1]代表当前天天打算在u这个城市玩两天。
当二维是0的时候,
dp[u][0]+=(dp[to][0]+1)*(size[u]+1).
// 在城市u已经玩了一天,并且打算用一天的时间乘车去下一个站点
dp[u][0]+=(dp[u][1])*(size[u]+1);
// 在城市u再再玩一天。
dp[u][1]+=(dp[to][0]+1)*(size[u]).
// 在城市u已经玩了两天了,只能选择继续往下一个城市走。
AC代码:
1 #include2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 const int mod = 998244353; 6 const int maxn = 2e5+100; 7 int dp[maxn][2]; 8 vector<int>Edge[maxn]; 9 ll inv[maxn]; 10 void init() 11 { 12 inv[1]=1; 13 for(int i=2; i 14 { 15 inv[i]=((mod-mod/i)*inv[mod%i]+mod)%mod; 16 } 17 } 18 ll dfs(int u,int type) 19 { 20 if(dp[u][type]!=-1) 21 return dp[u][type]; 22 dp[u][type]=1; 23 if(type) 24 { 25 for(auto i:Edge[u]) 26 { 27 dp[u][type]=(dp[u][type]+(dfs(i,type^1)+1)*inv[Edge[u].size()]%mod)%mod; 28 } 29 } 30 else 31 { 32 for(auto i:Edge[u]) 33 { 34 dp[u][type]=(dp[u][type]+(dfs(i,type)+1)*inv[Edge[u].size()+1]%mod)%mod; 35 } 36 dp[u][type]=(dp[u][type]+(dfs(u,type^1)*inv[Edge[u].size()+1]%mod))%mod; 37 } 38 return dp[u][type]%mod; 39 } 40 int main() 41 { 42 init(); 43 int T; 44 scanf("%d",&T); 45 while(T--) 46 { 47 int n,m,st,ed; 48 scanf("%d %d",&n,&m); 49 for(int i=0;i<=n;i++){Edge[i].clear();} 50 for(int i=1; i<=m; i++) 51 { 52 scanf("%d %d",&st,&ed); 53 Edge[st].push_back(ed); 54 } 55 for(int i=1; i<=n; i++) 56 { 57 dp[i][0]=dp[i][1]=-1; 58 } 59 ll ans=dfs(1,0); 60 printf("%lld\n",ans); 61 } 62 return 0; 63 })