1. 程式人生 > 其它 >牛客IOI周賽22-普及組

牛客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;
}