传送门:https://codeforces.ml/contest/1326/problem/C
题意:
给你一个长度为n的序列,要求分成k份,使每一份中的max值和最大,输出最大的和和分组的方法数。
思路:
和一定就是最大的k个数的和了,那么难点就在分法,设前k大的数分别为a1,a2,...ak,他们的位置分别为x1,x2,...xk。此问题可以看成插板问题,板可以插在前k大的数字的后面到下一个数字前,那么每一对的位置则为xi+1-xi,然后乘起来就是答案了。
ac代码:
优先队列(我为什么要想得那么复杂啊我去):
1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 const int mod=998244353; 5 const int maxn=2e5+5; 6 typedef long long ll; 7 ll maxx,ans=1,num; 8 int n,k; 9 struct node{ 10 int x,pos; 11 }a[maxn]; 12 bool operator < (node a,node b){ 13 return a.x<b.x; 14 } 15 priority_queue <node> Q; 16 17 struct node2{ 18 int x,pos; 19 }b[maxn]; 20 bool operator < (node2 a,node2 b){ 21 return a.pos>b.pos; 22 } 23 priority_queue <node2> Q2; 24 25 26 27 int main(){ 28 cin>>n>>k; 29 for(int i=1;i<=n;i++){ 30 cin>>a[i].x; 31 a[i].pos=i; 32 Q.push(a[i]); 33 } 34 for(int i=1;i<=k;i++){ 35 node now=Q.top(); 36 Q.pop(); 37 maxx+=now.x; 38 node2 cao; 39 cao.x=now.x; 40 cao.pos=now.pos; 41 Q2.push(cao); 42 } 43 node2 caoni=Q2.top(); 44 Q2.pop(); 45 int last=caoni.pos; 46 for(int i=2;i<=k;i++){ 47 node2 now=Q2.top(); 48 Q2.pop(); 49 ans=(ans*(now.pos-last))%mod; 50 //cout<<" "<<now.pos-last-1<<endl; 51 last=now.pos; 52 //cout<<"*"<<now.pos<<endl; 53 } 54 //cout<<"***"<<ans<<endl; 55 cout<<maxx<<" "<<ans; 56 return 0; 57 }
简简单单法:
#include<iostream> using namespace std; typedef long long ll; const int mod=998244353; int n,k,x; ll ans=1,sum,p=-1; int main() { cin>>n>>k; for(int i=1;i<=n;i++){ cin>>x; if(x>=(n-k+1)){ sum+=x; if(p!=-1){ ans=ans*(i-p)%mod; } p=i; } } cout<<sum<<" "<<ans; return 0; }