AtCoder Beginner Contest 226(EF补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 226(EF补题)相关的知识,希望对你有一定的参考价值。

E - Just one

链接: link.

题意:

N N N个点 M M M条无向边,现在给每个边定一个方向,总计 2 M 2^M 2M种方案,但现在规定每个点的出度为 1 1 1,且仅为 1 1 1(有且仅有一条出边),现在问有多少种方案?

思路:

要想将无向图定向,是每个点的出度为 1 1 1,那就需要每个点都有一条出边,此时就可以按照点数和边数的关系来分类讨论。
1.对于一个连通图来说 如果点数 > > >边数,要么是不连通图(与定义矛盾),要么就是一颗树,无法实现每个点都有出边,因为点数的边数不对应,一定会有一条边没有出边
2.对于一个连通图来说,如果点数 < < <边数,由于要实现每个点都有一条出边,那么可以先使每个点都出去一条边,此时用了一些边,但是还有一些边没有定方向,由于所有点的定了一个出去的方向,再给某个点定一个出边的话,就与题意矛盾,所以这种情况也不行
3.对于一个连通图,如果点数 = = =边数,说明这个连通图有一个环,且恰好能使每个点有一个出边。
讨论出来以后,就找每个连通块是否是点数 = = =边数,如果是的话,就有两种定方向(向左向右)的方案,对答案的贡献就是 ✖ ✖ 2
代码和思路是参考官方题解来写的

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int N=2e5+10;
#define ll long long
vector<int> e[N];
int n,m;
bool vis[N];
int x,y;

void dfs(int u) 
    vis[u]=1;
    x++;
    y+=e[u].size();
    for(int i=0;i<e[u].size();i++) 
        int j=e[u][i];
        if(!vis[j]) 
            dfs(j);
        
    

int main() 
    cin>>n>>m;
    for(int i=0;i<m;i++) 
        int a,b;
        scanf("%d%d",&a,&b);
        e[a].push_back(b);
        e[b].push_back(a);
    
    if(n!=m) 
        puts("0");
        return 0;
    
    ll res=1;
    for(int i=1;i<=n;i++) 
        if(!vis[i]) 
            x=0,y=0;
            dfs(i);
            if(x*2==y) 
                res=(ll)res*2%mod;
             else
                res=0;
                break;
            
        
    
    cout<<res<<endl;

F - Score of Permutations

链接: link.

题意:

对于一个 1 到 N 1到N 1N的排列 P P P = ( P 1 , P 2 . . . . P n ) =(P_1,P_2....P_n) =(P1,P2....Pn),对产生一个分数贡献 S ( P ) S(P) S(P) S ( P ) S(P) S(P)的定义为自然排列 P ′ = ( 1 , 2..... N ) P'=(1,2.....N) P=(1,2.....N)通过置换再次编程自然排列的最小次数。置换的意思就是每个 i ! = P i i!=P_i i!=Pi的人,都会把自己的球给 P i P_i Pi号人,一开始每个人 i i i号人,都会又 i i i号球,然后开始置换。现在问 1 到 N 1到N 1N的排列产生的贡献的 k k k次方的和。

思路:

样例(2,3,1)解释,就是一开始(1,2,3)然后(3,1,2)再(2,3,1)最后变成(1,2,3),一共3步。
对于一个排列 P P P,可以把里面的数字看成 m m m个循环,即 m m m个环,每一个点 i i i指向 P i P_i Pi,就会形成多个循环环,例如 N = 5 , P = ( 2 , 5 , 4 , 3 , 1 ) N=5,P=(2,5,4,3,1) N=5,P=(2,5,4,3,1),里面就会有两个环 3 − > 4 − > 3.... 和 1 − > 2 − > 5 − > 1.. 3->4->3....和1->2->5->1.. 3>4>3....1>2>5>1..长度分别为2和3,最终恢复成自然排列的最小次数是 l c m ( 2 , 3 ) = 6 lcm(2,3)=6 lcm(2,3)=6,一个排列会产生的贡献通过打表找规律发现是 l c m ( k 1 , k 2 . . . . k m ) lcm(k_1,k_2....k_m) lcm(k1,k2....km)
然后可以定义 f ( i , j ) f(i,j) f(i,j) i i i个人,所有环的长度的lcm为 j j j的方案数
f ( i + x , l c m ( j , x ) ) + = f ( i , j ) ∗ C n − i − 1 x − 1 ∗ ( x − 1 ) ! f(i+x,lcm(j,x))+=f(i,j)*C_n-i-1^x-1*(x-1)! f(i+x,lcm(j,x))+=f(i,j)Cni1x1(x1)!
为了防止出现重复,选择 x x x个人的时候,第一个人要先选剩下的人中编号最小的人,每个环内的最小值一定值单调递增的,所以就是 C n − i − 1 x − 1 C_n-i-1^x-1 Cni1x1,就因为第一个人被选出来了,而 x x x个人会形成 ( x − 1 ) ! (x-1)! (x1)!种循环排列。
对于 n n n个数的循环排列,会形成 ( n − 1 ) ! (n-1)! (n1)!种方案,而不是 n ! n! n!种方案,因为这不是全排列,而是循环排列
例如圈(1,2,3,4)和(2,3,4,1)都对应着同一个循环环1->2->3->4

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N = 55, mod = 998244353;
ll n, k;
ll fact[N], infact[N];
map<ll, ll> dp[N];

ll qmi(ll a, ll k) 
    ll res = 1;
    while (k) 
        if (k & 1) res = (ll)res * a % mod;
        k >>= 1;
        a = a * a%mod;
    
    return res;


void init() 
    fact[0]=infact[0]=1;
    for(int i=1;i<N;i++) 
    
        fact[i]=(ll)fact[i-1]*i%mod; 
        infact[i]=(ll)infact[i-1]*qmi(i,mod-2)%mod; 
    


ll C(ll a, ll b) 
    if (a < b) return 0;
    return fact[a] * infact[b] % mod * infact[a - b] % mod;


ll gcd(ll a, ll b)  return !b ? a : gcd(b, a % b); 
ll lcm(ll a, ll b)  return a / gcd(a, b) * b; 



int main() 
    init();
    cin >> n >> k;
    dp[0][1] = 1;
    for (int i = 0; i < n; i++) 
        for (auto it : dp[i]) 
            for (int j = 1; i + j <= n; j++) 
                dp[i + j][lcm(j, it.first)] = (dp[i + j][lcm(j, it.first)] + it.second * C(n - i - 1, j - 1) %mod * fact[j - 1] % mod) % mod;
            
        
    
    ll res = 0;
    for (auto it : dp[n]) 
        res = (res + it.second * qmi(it.first, k)) % mod;
    
    cout << res << endl;

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于AtCoder Beginner Contest 226(EF补题)的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242