Comet OJ 夏季欢乐赛 H
分配学号
题目描述
今天,是JWJU给同学们分配学号的一天!为了让大家尽可能的得到自己想要的学号,鸡尾酒让大家先从 [1,10^{18}][1,1018] 中随机挑选一个数字作为自己的学号。但是总有一些心有灵犀的小伙伴们选择了一样的数字——显然这样是不合法的,因为每个人的学号都应该是唯一的。
于是鸡尾酒决定调整大家的学号。他采用如下两个原则来修改:
1、只增不减,每个人的最终学号 \ge≥ 每个人初始选择的学号
2、总修改量尽量少,总修改量指每一个人的改动量之和。(改动量即为最终学号减初始学号的值)
注意,修改后的最终学号可以大于10^{18}1018。
很显然,如果现在有两个同学 A 和 B,初始选择的学号均为1号,他们有可能被鸡尾酒改动成 A 同学为 11 号和 B 同学为 22 号,或者改动成 B 同学为 11 号和 A 同学为 22 号。
鸡尾酒邪魅一笑,他想让你告诉他,大家的最终学号共有多少种不同的分配方案。
输入描述
第一行包含一个正整数 nn,代表学生的数量。(1 \le n \le 10^{5})(1≤n≤105)
接下来一行包含 nn 个正整数,分别代表每个学生的初始选择的学号。(取值范围[1,10^{18}])[1,1018])
输出描述
输出一个整数表示最终学号的方案数。(答案对 10^{9}+7109+7 取模)
在两个最终学号的分配方案中,若存在某一个学生在两个方案中的学号不相同,则认为是这两个方案是不同的分配方案。
样例输入 1
3 1 1 2
样例输出 1
4
样例输入 2
2 1 5
样例输出 2
1
对于第一组样例,最终的学号分配方案有以下4种:
[1,2,3],[1,3,2],[2,1,[3,2][1,2]
分配之后每个学生的学号均不相同,且这几种方案的总修改量都是最小的。
对于第二组样例,每个学生的学号已经都不相同,所以无需修改,所以最终分配方案只有11种,即[1,5][1,5]。
CODE:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5,mod=1e9+7; ll a[N]; ll pos[N]; ll lst; int n; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+n+1); for(int i=1;i<=n;i++) { if(lst>=a[i]) pos[i]=lst+1,lst++; else lst=a[i],pos[i]=a[i]; } int ans=1; for(int i=1;i<=n;i++) ans=ans*(pos[i]-a[i]+1)%mod; printf("%d\n",ans); return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。