CF Educational Round 83

CF Educational 83


A.数学##

给定n,m,问你能否用一个正n边形的m个顶点,使之连成一个正m边形

判断n/m*m==n即可

B.构造##

给定序列A

使得i<j时,j−Aj≠i−Ai

从大到小排序即可

C.数学##

给定n,以及k,n个非零数,

一开始你有n个0,第i次操作你可以使得任意一个数加上ki-1,或者跳过第i次操作

问你能否在任意次操作后,使得这个全0序列变成给定序列

思路:把给定的n个非零数,按照k进制分解储存,只要有一位大于1,那么肯定不能实现

#include<iostream>
#include<cstring>

using namespace std;
	
#define INF 1e10+5
#define MAXN 105
#define MINN -105
typedef long long int LL;
LL a[MAXN],b[MAXN];
LL n,k;
bool ok;
void check(LL& i,LL j,LL cur)
{
	    if(cur>i)return;
    check(i,j+1,cur*k);
    if(cur<=i)
    {
        i-=cur;
        b[j]++;
        if(b[j]>=2){ok=0;return;}
    }
}

void solve()
{
    memset(b,0,sizeof(b));
    cin>>n>>k;
    for(int i=0;i<n;i++)
        cin>>a[i];
    for(int i=0;i<n;i++)
    {
        ok=1;
        if(!a[i])continue;
        check(a[i],0,1);
        if(a[i])ok=0;
        if(!ok)
        {
	            cout<<"NO"<<endl;
        return;
	        }
    }

    cout<<"YES"<<endl;
}


int main()
{
    int t;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        solve();
    }
    return 0;
}

D.逆元##

题意:

给定n,m

问你有多少序列,使得:

1)有n个元素

2)有且仅有两个值

3)取值1到m

4)单峰序列

答案取模998244353

思路:从m个数中取n-1个数,C(m,n)这里数很大,除法要变成乘以逆元计算。因为序列是单峰,所以最大值的位置确定,n-2个数数中取一个数,使得它有等值数,他们分居最大值左右,位置确定,所以对于接下来的n-3个数,它能选左选右,共2n-3

乘法原理计算即可

#include<iostream>
#include<cstring>

using namespace std;

#define INF 1e10+5
#define MAXN 105
#define MINN -105
typedef long long int LL;

LL mo=998244353;
LL ans=1;
LL up(LL k,LL num)
{
    LL awsl=1;
    while(k)
    {
        if(k&1)awsl=(awsl*num)%mo;
        k/=2;
        num=(num*num)%mo;
    }
    return awsl%mo;
}
LL getx(LL a)
{
    if(a==1)return 1;
    return up(mo-2,a);
}
int main()
{
    LL n,m;
    cin>>n>>m;
    ans=1;
    for(LL i=1;i<=n-1;i++)
        ans=(ans*(m-i+1)%mo*getx(i))%mo;
    ans*=up(n-3,2);
    ans%=mo;
    ans*=(n-2);
    ans%=mo;
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/et3-tsy/p/12461490.html