CF757C Felicity is Coming!

1 CF757C Felicity is Coming!

2 题目描述

时间限制 \(2s\) | 空间限制 \(256M\)

It's that time of the year, Felicity is around the corner and you can see people celebrating all around the Himalayan region. The Himalayan region has n gyms. The i-th gym has gi Pokemon in it. There are m distinct Pokemon types in the Himalayan region numbered from 1 to m. There is a special evolution camp set up in the fest which claims to evolve any Pokemon. The type of a Pokemon could change after evolving, subject to the constraint that if two Pokemon have the same type before evolving, they will have the same type after evolving. Also, if two Pokemon have different types before evolving, they will have different types after evolving. It is also possible that a Pokemon has the same type before and after evolving.

Formally, an evolution plan is a permutation f of {1, 2, ..., m}, such that f(x) = y means that a Pokemon of type x evolves into a Pokemon of type y.

The gym leaders are intrigued by the special evolution camp and all of them plan to evolve their Pokemons. The protocol of the mountain states that in each gym, for every type of Pokemon, the number of Pokemon of that type before evolving any Pokemon should be equal the number of Pokemon of that type after evolving all the Pokemons according to the evolution plan. They now want to find out how many distinct evolution plans exist which satisfy the protocol.

Two evolution plans \(f_1\) and \(f_2\) are distinct, if they have at least one Pokemon type evolving into a different Pokemon type in the two plans, i. e. there exists an i such that \(f_1(i) ≠ f_2(i)\).

Your task is to find how many distinct evolution plans are possible such that if all Pokemon in all the gyms are evolved, the number of Pokemon of each type in each of the gyms remains the same. As the answer can be large, output it modulo \(10^9 + 7\).

数据范围:\(1 ≤ n ≤ 10^5, 1 ≤ m ≤ 10^6\)

3 题解

性质:如果两个宝可梦在所有场馆中数量都相等,那么这两个宝可梦一定可以互相进化。这是因为这两个宝可梦互相进化了之后每个场馆中的这两种宝可梦数量都不会改变。因此,我们可以考虑用 \(vector\) 存储每一种宝可梦在每个场馆中的分布。这样以来,如果两个宝可梦的分布一样,我们就可以选择将这两个宝可梦互相进化。

注意到一个性质,如果我们有 \(n\) 个宝可梦可以互相进化,那么我们一共的方案数就是 \(n!\),这是因为我们可以在这 \(n\) 个宝可梦中选取全排列种方案。根据这个性质,我们可以将 \(vector\) 从小到大排序,其中相同的宝可梦个数 \(cnt\) 就代表有 \(cnt\) 个宝可梦可以互相进化。然后统计答案即可。

4 代码(空格警告):

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
const int M = 1e6+10;
const int mod = 1e9+7;
#define int long long
int n, m, x, ans, cnt, g;
vector<int> v[M];
signed main()
{
    ans = 1;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> g;
        for (int j = 1; j <= g; j++)
        {
            cin >> x;
            v[x].push_back(i);
        }
    }
    sort(v+1, v+m+1);
    for (int i = 1; i <= m; i++)
    {
        if (v[i] == v[i-1])
        {
            cnt++;
            ans = (ans * cnt) % mod;
        }
        else cnt = 1;
    }
    cout << ans;
    return 0;
}

欢迎关注我的公众号:智子笔记

posted @ 2021-04-01 23:15  David24  阅读(93)  评论(0编辑  收藏  举报