牛客IOI周赛22-普及组

题目链接

牛客IOI周赛22-普及组

C.照看小猫

题目描述

在一个风和日丽的午后,少佐给薇尔莉特伊芙嘉登安排了一个任务。
任务大致是这样的,接下来的一周,薇尔莉特需要昭顾 \(\mathrm{N}\) 只小猫咪。为了方便管理这 \(\mathrm{N}\) 只猫咪, 薇尔莉特准备给每只猫咪取一个独一无二的名字。取名字要征求猫咪本咪的同意才可以。
但这些猫咪都非常有个性,绝不接受很长的名字。
现给出每只猫咪所能容忍名字的长度上限。
请你为所有猫咪取多字,请问共有多少种不同的方案。
多字仅包含小写英文字母。结果可能非常大,所以请将结果对 \(77797\) 取模
如果无方案,请输出 \(-1\)

输入描述:

第一行, 一个正整数 \(\mathrm{N}\)
第二行, \(\mathrm{N}\) 个正整数, 第 \(i\) 个数孕 \(a_{i}\), 表示第 \(i\) 只猫咪所能容忍名孕的长度上限, 数字间以空格隔开。

输出描述:

第一行, 仅输出 \(1\) 个数, 取模后的总方案数 \(\mathrm{x}\) 。 PS: 如果无方案, 请输出 \(-1\)

示例1

输入

1 1

输出

26

说明

猫咪的名字可以为 \(a-z\) 间的任意一个孕母, 所以方安数为 26 。

示例2

输入

1 2

输出

702

说明

样例 \(2\) 中, 猫咪的名字的长度可以为 \(1\) , 也可以为 \(2\)
长度为 \(1\) 时, 名字可以为 \(a-z\) 中任意一个, 方案数 \(26\) 种。
长度为 \(2\) 时, 名字可以为 \(a a-a z , b a-b z , \ldots, z a-z z\) 中任意一个, 方案数 \(26 \times 26=676\) 种。 所以总方案数为 \(26+676=702\) 种。

示例 3

输入

5
7 5 8 4 3

输出

9416

备注:

\(100\%\) 的数据, \(1 \leq N \leq 10^{4}, 1 \leq a_{i} \leq 10\)

解题思路

容斥原理

先将长度排序,计算该长度可用的方案数,减去前面的数量(由于当前长度不小于前面的所有长度,所以当前所有方案一定包含前面的方案数)即为实际可用方案数,此时和前面的方案数互不影响,乘积即为总方案数

  • 时间复杂度:\(O(nlogn)\)

代码

// Problem: 照看小猫
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/32950/C
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e4+5,mod=77797;
int n,a[N];
LL b[N];
void init()
{
	b[1]=26;
	for(int i=2;i<=10;i++)b[i]=26*b[i-1];
	for(int i=2;i<=10;i++)b[i]+=b[i-1];
}
int main()
{
	init();
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    LL res=1;
    for(int i=1;i<=n;i++)
    {
    	LL t=b[a[i]]-i+1;
    	if(t<=0)
    	{
    		puts("-1");
    		return 0;
    	}
    	res=1ll*res*t%mod;
    }
    cout<<res;
    return 0;
}
posted @ 2022-04-15 20:55  zyy2001  阅读(41)  评论(0编辑  收藏  举报