CF1326C Permutation Partitions 题解

36 篇文章 1 订阅
16 篇文章 1 订阅
博客内容简述:这是一篇关于CF1326C Permutation Partitions问题的解题文章。题目要求给定1~n的置换,找到最佳分区方案,使每个区间的最大值之和最大化。解决方案的关键在于处理1~n的置换,通过特定策略确定最大值的分配。文章详细介绍了如何确定最大值的分布,并给出计算方案数的方法,涉及到位置差异的乘积计算。
摘要由CSDN通过智能技术生成

博客园同步

原题链接

简要题意:

给定一个 1 1 1 ~ n n n 的置换,将数组分为 k k k 个区间,使得每个区间的最大值之和最大。求这个值,和分区的方案数。

关键在于 1 1 1 ~ n n n 的置换。

显然,你只要把从 n − k + 1 n - k + 1 nk+1 n n n 这一段,每个区间分一个(其余的随便分)。

显然可以得出第一个答案:

( n − k + 1 ) + ( n − k + 1 ) + ⋯ + ( n − 1 ) + n (n-k+1) + (n-k+1) + \cdots + (n-1) + n (nk+1)+(nk+1)++(n1)+n

(很显然,你可以用等差数列求和,可是没这个必要,一会儿求第二个答案的时候,可以顺便求啊

比方说:(以第三个样例为例)

7 3
2 7 3 1 5 4 6

这时你把 5 5 5 6 6 6 7 7 7 作为每个区间的最大值。

此时你会发现,比方说 3   1 3 \space 1 3 1 这一段。

它要么全归 7 7 7,全归 5 5 5 ,或者分两段,左边归 7 7 7,右边归 5 5 5.

那么,你想,这就相当于你可以在任意的位置把它分段。(包括最左边和最右边,此时尽属一段)

那么,方案数是 3 3 3.

就是 5 5 5 的位置减去 7 7 7 的位置,即 5 − 2 = 3 5 - 2 = 3 52=3.

而一共三段,分别计算。根据 乘法原理 可得:

1 × 3 × 2 = 6 1 \times 3 \times 2 = 6 1×3×2=6

所以,第二个答案是:

每个 ≥ n − k + 1 \geq n - k + 1 nk+1 的数和前面一个 ≥ n − k + 1 \geq n - k + 1 nk+1 的数的位置之差的乘积。

第零个 ≥ n − k + 1 \geq n - k + 1 nk+1 的数的位置,我们认为是 0 0 0.

记得开 long   long \texttt{long long} long long.

十年OI一场空,不开long long见祖宗

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MOD=998244353;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int n,k,last;
ll s=0,cnt=1;

int main(){
	n=read(),k=read();
	for(int i=1,t;i<=n;i++) {
		t=read(); if(t>n-k) {
			s+=t; if(!last) last=i; //维护上一个 >= n - k + 1 的数的位置
			else cnt=cnt*(i-last)%MOD,last=i; //计数
		} 
	} printf("%lld %lld\n",s,cnt); 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值