2017 CCPC 杭州

Time:

Link


A

题意

分析


B

题意

分析

 ym:积性函数 ( 没看懂网上题解

          update: 回过头冷静下来仔细看了看,发现挺简单的啊,分析过程可以看我的blog(https://kzpx.github.io/2018/09/08/2017%20CCPC%20Hangzhou%20Onsite/)

czh:d|n,d由一串素数相乘而来,对于m个素数,有选取与不选取两种状态,如果选取了有pi种选取方法,即选1到pi个,根据欧拉函数的公式,一个数的欧拉值只与它含有的素因子有关。一共有2^20种欧拉值。对于某种欧拉值又有qa*qb*qc..次被使用,其中qaqbqc,对应的pa,pb,pc...构成了d

直接用状态压缩,2^20*m*T=4*1e8,刚好超时,所以用dfs,复杂度为2^20

还是对欧拉函数不够熟练

参考:https://blog.csdn.net/weixin_38327682/article/details/79988278

#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int maxn=25;
const int mod=998244353;
ll p[maxn],q[maxn],G[maxn],ans,n;
int m;
ll qpow(ll a,ll b)
{
    ll res=1,k=a;
    while(b)
    {
        if(b&1)res=(res*k)%mod;
        k=(k*k)%mod;
        b=b>>1;
    }
    return res;
}
void dfs(int x,ll now)
{
    for(int i=0; i<=1; i++)
    {
        if(x==m)
        {
            if(i==1)
                ans=(ans+now*G[x]%mod)%mod;
            else ans=(ans+now)%mod;
        }
        else
        {
            if(i==1)
                dfs(x+1,now*G[x]%mod);
            else dfs(x+1,now);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        n=1;
        scanf("%d",&m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d",&p[i],&q[i]);
            n=qpow(p[i],q[i])*n%mod;
            G[i]=q[i]%mod*(p[i]-1)%mod*qpow(p[i],mod-2)%mod;
        }
        ans=0;
        dfs(1,n);
        printf("%lld
",ans);
    }
    return 0;
}

  


C

题意

分析

 ym:网上题解说的很有道理啊

czh:当d=1时只有n全是1且n%3==0是才会输,同样,d=2时,只有先手可以将状态转换成前一个状态时才输

如果d=1 且面对的不是上面的状态,那么先手有办法使石子堆数保持在n%3!=0,那么他就无论如何都输不了了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+100;

int T, d, n, a[maxn];

int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &d);
        int cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d", &a[i]);
            if(a[i] == 1)
                cnt++;
        }
        if(d==1){
            if(n%3==0 && cnt==n)
                puts("No");
            else
                puts("Yes");
        }
        else{
            if(n%3==1){
                if(cnt>=n-1)
                    puts("No");
                else
                    puts("Yes");
            }
            else if(n%3==0 && cnt==n-1)
                puts("No");
            else
                puts("Yes");
        }
    }
}

D

题意

分析

ym:找到规律后,就很简单了(可是这规律真能看出来???x掉

        正解:推公式  设dp[i]是i选中的概率 , dp[i]=(dp[1]+...dp[i-1])*(1/(i-1))+1/n

 czh:。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
const ll mod=998244353;

int T, n;
ll a[maxn], fac[maxn], sum[maxn];

void init()
{
    fac[0]=1;
    for(int i=1;i<=100000;i++)
        fac[i]=(fac[i-1]*i)%mod;
}

ll quick(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans = (ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}

int main()
{
    init();
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i=1;i<=n;i++)
            scanf("%lld", &a[i]);
        ll ans=0;
        sum[1]=fac[n-1];
        ans = (ans + sum[1] * a[1]) %mod;
        for(int i=2;i<=n;i++)
        {
            sum[i]=(sum[i-1]+(fac[n-1]*quick(i-1, mod-2))%mod)%mod;
            ans=(ans + sum[i] * a[i] %mod) %mod;
        }
        ans=(ans * quick(fac[n], mod-2))%mod;
        printf("%lld
", ans);
    }
    return 0;
}

  


E

题意

分析


F

题意

分析


G

题意

分析


H

题意

分析


I

题意

分析


J

题意

分析

 ym:题解(https://kzpx.github.io/2018/09/08/2017%20CCPC%20Hangzhou%20Onsite/)


K

题意

分析

  ym:题解(https://kzpx.github.io/2018/09/08/2017%20CCPC%20Hangzhou%20Onsite/)


Summary:

Ym:铁牌++

Czh:

原文地址:https://www.cnblogs.com/Deadline/p/9601892.html