2019CCPC秦皇岛

D - Decimal

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int main()
{
    int n,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(maxn%n==0)
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}

F - Forest Program

题意:

给出一个 \(n\) 个点,\(m\) 条边的图,图中不包含自环,重边,并且一条边最多只出现在一个环中。求出去掉一些边后,图中剩余部分全部是树的方案数,模 \(998244353\)

分析:

根据 \(1\) 条边最多出现在一个环中,用 \(dfs\) 来找环,并且求出每个环的边数。然后,用组合数学,二项式定理求解。

代码:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef pair<int,int>P;
typedef long long ll;
const int N=3e5+5;
const int mod=998244353;
vector<int>pic[N];
int dis[N],cir[N];
int cnt,n,m;
void dfs(int v,int p,int d)
{
    if(dis[v]>-1)
    {
        if(d<=dis[v]) return;
        cir[++cnt]=d-dis[v];
        return;
    }
    dis[v]=d;
    for(int i=0;i<pic[v].size();i++)
    {
        int u=pic[v][i];
        if(u==p) continue;
        dfs(u,v,d+1);
    }
}
ll power(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res%mod;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        cnt=0;
        int u,v;
        for(int i=1;i<=n;i++)
        {
            pic[i].clear();
            dis[i]=-1;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            pic[u].pb(v);
            pic[v].pb(u);
        }
        dfs(1,0,0);
        int t=0;
        ll ans=1;
        for(int i=1;i<=cnt;i++)
            t+=cir[i];
        t=m-t;
        for(int i=1;i<=cnt;i++)
             ans=(ans*(power(2LL,1LL*cir[i])-1LL))%mod;
        ans=ans*power(2LL,t)%mod;
        printf("%lld\n",(ans+mod)%mod);
    }
    return 0;
}

I - Invoker

线性DP。
https://www.cnblogs.com/1024-xzx/p/12991711.html

J - MUV LUV EXTRA

英文题目没看懂。
中文题面:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1010&cid=872
把字符串反向,KMP最小循环节,枚举遍历取最优。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+5;
const int inf=0x3f3f3f3f;
int a,b;
char ss[N];
int nxt[N];
void getnxt(int len)
{
    int k=-1,j=0;
    nxt[0]=-1;
    while(j<len)
    {
        if(k==-1||ss[j]==ss[k]) nxt[++j]=++k;
        else k=nxt[k];
    }
}
int main()
{
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        scanf("%s",ss);
        int len=strlen(ss),p=1;
        for(int i=0;i<len;i++)
        {
            if(ss[i]=='.')
            {
                p=i+1;
                break;
            }
        }
        for(int i=p;i<len;i++)
            ss[i-p]=ss[i];
        len=len-p;
        ss[len]='\0';
        for(int i=0;i<len/2;i++)
        {
            char t=ss[len-i-1];
            ss[len-i-1]=ss[i];
            ss[i]=t;
        }
        getnxt(len);
        ll ans=-inf;//取足够小
        for(int i=1;i<=len;i++)
        {
            ll t=1LL*a*i-1LL*b*(i-nxt[i]);
            ans=max(ans,t);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

A - Angle Beats

计算几何。

K - MUV LUV UNLIMITED

树上博弈。
https://www.cnblogs.com/1024-xzx/p/13027909.html

posted @ 2020-05-31 22:40  xzx9  阅读(195)  评论(0编辑  收藏  举报