四连测Day3

三连爆炸

极端快乐

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");
    }
}
View Code

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]<<" ";
}
View Code

状压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;
}
View Code
原文地址:https://www.cnblogs.com/Kong-Ruo/p/9448415.html