三连爆炸
极端快乐
T1
判断一个无向图能不能一笔画
小学奥数 记得判图连不连通
#include<bits/stdc++.h> using namespace std; inline int read() { int x = 0,f = 1;char ch = getchar(); for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f; for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0'; return x * f; } const int maxn = 1e5 + 10; int n,m,ind[maxn]; int fa[maxn]; inline int getfa(int x){return x == fa[x] ? x : fa[x] = getfa(fa[x]);} int main() { freopen("euler.in","r",stdin); freopen("euler.out","w",stdout); int T = read(); while(T--) { int cntj = 0;memset(ind,0,sizeof(ind)); n = read();m = read(); for(int i=1;i<=n;i++)fa[i] = i; for(int i=1;i<=m;i++) { int u = read(),v = read(); ind[u]++;ind[v]++; fa[getfa(u)] = getfa(v); } int flag = 0; for(int i=1;i<=n;i++)if(getfa(i) != getfa(1)){puts("NO");flag = 1;break;} if(flag)continue; for(int i=1;i<=n;i++)if(ind[i] & 1)cntj++; if(cntj == 0 || cntj == 2)cout<<"YES "; else puts("NO"); } }
T2
现在每个人都有1/2的概率当场去世
现在有m条愿望,每条愿望是一个名单里的人不会当场去世
求正好满足i条愿望的概率
愿望条数<=5
#include<bits/stdc++.h> #define int long long using namespace std; inline int read() { int x = 0,f = 1;char ch = getchar(); for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f; for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0'; return x * f; } const int maxn = 1e5 + 10,mod = 998244353,inv2 = 499122177; inline int ksm(int x,int k) { int ans = 1; while(k) { if(k & 1)ans = (ans * x) % mod; x = (x * x) % mod; k = k >> 1; } return ans; } int n,m; int wi[maxn][10]; int dp[(1 << 5) + 5][maxn]; inline int inv(int x){return ksm(x,mod - 2);} inline int div2(int x){return (x * inv2) % mod;} inline int cnt(int x) { int ret = 0; for(int i=0;i<=n;i++) if(x & (1 << i))ret++; return ret; } signed main() { freopen("avengers3.in","r",stdin); freopen("avengers3.out","w",stdout); n = read(),m = read();int MAXSTATE = (1 << n) - 1; for(int i=1;i<=n;i++) { int k = read(); for(int j=1;j<=k;j++) { int u = read(); wi[u][i] = 1; } }dp[MAXSTATE][0] = 1; for(int i=0;i<m;i++) for(int S=MAXSTATE;S>=0;S--) { if(!dp[S][i]) continue; (dp[S][i + 1] += (dp[S][i] * inv2) % mod) %= mod; int TS = S;for(int j=1;j<=n;j++)if(wi[i + 1][j] && ((1 << (j - 1)) & S))TS -= (1 << (j - 1)); (dp[TS][i+1] += (dp[S][i] * inv2) % mod) %= mod; } int ans[10];memset(ans,0,sizeof(ans)); for(int S=0;S<=MAXSTATE;S++)(ans[cnt(S)] += dp[S][m]) %= mod; for(int i=0;i<=n;i++)cout<<ans[i]<<" "; }
状压dp
dp[i][S]表示前i个人,有可能满足S中愿望的概率
1.dp[0][MAXS] = 1
2.dp[i + 1][S] += (dp[i][S] / 2)(i + 1没有去世)
3.dp[i + 1][S & TS] += (dp[i][S] / 2)(i + 1当场去世 TS为不包含i +1的愿望的集合)
T3 询问一个长度为n的字符串中有多少个不包含s
GT考试了解一下
#include<bits/stdc++.h> #define int long long using namespace std; inline int read() { int x = 0,f = 1;char ch = getchar(); for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f; for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0'; return x * f; } const int maxn = 55; int tlen,mlen; string n; char str1[maxn],P[maxn]; int f[maxn];const int mod = 998244353; string div(string a,int b) { string r,ans; int d=0; if(a=="0") return a; for(int i=0;i<a.size();i++) { r+=(d*10+a[i]-'0')/b+'0'; d=(d*10+(a[i]-'0'))%b; } int p=0; for(int i=0;i<r.size();i++) if(r[i]!='0') {p=i;break;} return r.substr(p); } struct Matrix { int n,m,a[maxn][maxn]; Matrix() { memset(a, 0, sizeof(a)); n = m = mlen; for(int i = 0; i < n; i++) a[i][i] = 1; } void clear() { n = m = 0; memset(a, 0, sizeof(a)); } Matrix operator * (const Matrix& b) const { Matrix t; t.clear(); t.n = n; t.m = b.m; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) for(int k = 0; k < m; k++) (t.a[i][j] += a[i][k] * b.a[k][j]) %= mod; return t; } Matrix operator ^ (string k) { Matrix ans,t = *this;int len; while(1) { len = k.length(); if((k[len - 1] - '0') & 1)ans = ans * t; t = t * t; k = div(k,2); if(k == "0")break; } return ans; } }; void getFail() { int m = strlen(P); f[0] = 0; f[1] = 0; for(int i = 1; i < m; i++) { int j = f[i]; while(j && P[i]!=P[j]) j = f[j]; f[i+1] = P[i]==P[j] ? j+1 : 0; } } signed main() { freopen("string.in","r",stdin); freopen("string.out","w",stdout); cin>>n>>P; for(int i=0;i<26;i++)str1[i] = 'a' + i; tlen = strlen(str1), mlen = strlen(P); getFail(); Matrix ans; ans.clear(); ans.n = ans.m = mlen; for(int i = 0; i < mlen; i++) { for(int j = 0; j < tlen; j++) { int t = i; while(t && P[t]!=str1[j]) t = f[t]; if(P[t] == str1[j]) t++; ans.a[i][t]++; } } ans = ans ^ n; int ret = 0; for(int i = 0; i < mlen; i++) (ret += ans.a[0][i]) %= mod; cout<<ret; return 0; }