Comet OJ 夏季欢乐赛 分配学号
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("%dn",ans); return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |