NC230852. Cards of Magic
描述
输入描述
The only line contains a single integer , indicating the monster's HP.
输出描述
Output a line containing an integer, indicating the expected number of turns to defeat the monster modulo if playing optimally.
More precisely, if the reduced fraction of the answer is , what you should provide is the minimum nonnegative integer such that . You may safely assume that such always exists.
示例1
输入:
1
输出:
831870296
说明:
In the first sample case:示例2
输入:
5
输出:
835978299
C++ 解法, 执行用时: 60ms, 内存消耗: 33684K, 提交时间: 2021-11-29 09:15:29
#include<bits/stdc++.h> using namespace std; const int mod = 998244353; int n; int iv[15]; int dp[300105][2][2][3]; bool vis[300105][2][2][3]; int getdp(int fire, int has, int water, int cpy) { if (vis[fire][has][water][cpy]) return dp[fire][has][water][cpy]; vis[fire][has][water][cpy] = 1; if (water) { if ((cpy == 2) || (!has && fire + 2 * cpy >= n) || (has && 4 * cpy + fire >= n)) return dp[fire][has][water][cpy] = 1; int ans = (getdp(fire + 1, has, 1, cpy) + getdp(fire, has, 1, cpy + 1)) % mod; ans = (ans + getdp(fire + 3, 1, 1, cpy)) % mod; ans = 1ll * ans * iv[3] % mod; ans = (ans + 1) % mod; return dp[fire][has][water][cpy] = ans; } else { if (!has && (cpy * 2 + fire + 2 >= n) && cpy >= 2) return dp[fire][has][water][cpy] = 5ll * iv[2] % mod; if (has && (fire + cpy * 2 >= n)) return dp[fire][has][water][cpy] = 1; int ans = (getdp(fire + 2, 1, 0, cpy) + (cpy < 2 ? getdp(fire, has, 0, cpy + 1) : getdp(fire + 2, has, 0, 2))) % mod; ans = (ans + getdp(fire / 2 * 3, has, 1, cpy)) % mod; ans = 1ll * ans * iv[3] % mod; ans = (ans + 1) % mod; return dp[fire][has][water][cpy] = ans; } } signed main() { #ifdef Sakuyalove freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(0); iv[1] = 1; for (int i = 2; i <= 10; i++) iv[i] = 1ll * (mod - mod / i) * iv[mod % i] % mod; cin >> n; cout << (getdp(0, 0, 0, 0) + mod - 1) % mod << endl; return 0; }
C++(g++ 7.5.0) 解法, 执行用时: 18ms, 内存消耗: 2092K, 提交时间: 2022-11-09 16:44:00
#include<algorithm> #include<iostream> #include<cstdio> using namespace std; const int mo=998244353; const int inv2=(mo+1)>>1; const int inv3=(mo+1)/3; int jie[200005],inv[200005],n; int C(int o,int p){return (o<p)?0:(1ll*jie[o]*inv[p]%mo*inv[o-p]%mo);} int mi(int o,int p) { int yu=1; while(p) { if(p&1) yu=1ll*yu*o%mo; o=1ll*o*o%mo; p>>=1; } return yu; } int main() { jie[0]=1; for(int i=1;i<=200000;i++) jie[i]=1ll*jie[i-1]*i%mo; inv[200000]=mi(jie[200000],mo-2); for(int i=199999;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mo; scanf("%d",&n); int ans=1,cal=1,la=0; for(int i=1,fac=inv3;i<=n;i++,fac=1ll*fac*inv3%mo) { ans=(ans+1ll*fac*cal%mo)%mo; int yu=min(i,(n-i-1)>>1); cal=((cal+cal-C(i,la))%mo+mo)%mo; if(la>yu) { cal=(cal-C(i+1,la)+mo)%mo; }else if(la<yu) { cal=(cal+C(i+1,yu))%mo; } la=yu; } cal=3;la=1; for(int i=3,fac=1ll*inv3*inv3%mo*inv3%mo;i<=n-5;i++,fac=1ll*fac*inv3%mo) { ans=(ans+1ll*fac*i%mo*(cal-1)%mo)%mo; int yu=min(i-1,(n-i-4)>>1); cal=((cal+cal-C(i-1,la))%mo+mo)%mo; if(la>yu) { cal=(cal-C(i,la)+mo)%mo; }else if(la<yu) { cal=(cal+C(i,yu))%mo; } la=yu; } for(int i=2,fac=1ll*inv3*inv3%mo;i<=n-1;i++,fac=1ll*fac*inv3%mo) { ans=(ans+1ll*fac*i%mo)%mo; } for(int i=1,fac=inv3,cal=1;i<=(n-1)>>1;i++,fac=1ll*fac*inv3%mo,cal=(cal+cal+1)%mo) { ans=(ans+1ll*fac*cal%mo)%mo; } ans=(ans+inv2)%mo; cout<<ans<<endl; return 0; }