Codeforces Global Round 7 比赛人数10630
[codeforces 1326C] Permutation Partitions 排列组合
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
也在线测评地址https://codeforces.ml/contest/1326/problem/C
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Permutation Partitions | GNU C++11 | Accepted | 93 ms | 2200 KB |
思路:
自大到小排序,标记前K大的数据出现的位置,计算前K大的数据和,这是输出数据的第一项,在前K大的数据中,统计相邻两数间,其他元素的个数cnt。ans=ans*(cnt+1)这是输出数据的第二项。
手工算法如下
输入
7 3
2 7 3 1 5 4 6
7 3
2 7 3 1 5 4 6
最大数据7
第二大数据6
第三大数据5
和是7+6+5=18
2 7 (3 1) 5 (4) 6
7,5之间有2个数(3 1),可与7形成3种组合[2,7],[2,7,3],[2,7,3,1]
5,6之间有1个数(4),可与5形成2种组合[...,5],[...,5,4]
总的情况,就是3*2=6
AC代码如下
#include <cstdio>
#include <algorithm>
#define mod 998244353
#define maxn 200010
#define LL long long
using namespace std;
struct node{
int seq,v;//seq元素出现位置,v元素数值
}a[maxn];
int cmp(node a,node b){
return a.v>b.v;
}
int cnt[maxn];//标记前K大数据出现的位置
LL mx,num=1;
int main(){
int n,k,i;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)scanf("%d",&a[i].v),a[i].seq=i;
sort(a+1,a+1+n,cmp);//按数值,自大到小排序
for(i=1;i<=k;i++)cnt[i]=a[i].seq,mx+=a[i].v;
sort(cnt+1,cnt+1+k);//按出现位置,自小到大排序
for(i=2;i<=k;i++)num=num*(cnt[i]-cnt[i-1])%mod;
printf("%lld %lld\n",mx,num);
return 0;
}