CF1342D Multiple Testcases(构造题)

该博客介绍了如何解决CF1342D问题,这是一个涉及构造背包策略的数学题目。博主首先阐述了题目的具体要求,即在限制每个背包内特定数值个数的情况下,确定最小的背包数量。博主分析了比赛时采用的复杂方法,并给出了题解提供的简洁解法。解法主要包括计算所需背包总数cnt,然后对排序后的数值进行均匀分配。实现过程中,利用了抽屉原理和背包容量约束。最后,博主提供了问题的O(nlogn)时间复杂度的解决方案。

题意

n n n 个数 { a i } \{a_i\} {ai},每个 a i ≤ k a_i\leq k aik
每个背包大于等于 i i i 的数的个数不能超过 c i ( i = 1 , 2 , . . , k ) c_i(i=1,2,..,k) ci(i=1,2,..,k)
问最少要多少个背包才能放所有数,并且输出每个背包中的数。
n , k ≤ 200000 n,k \leq 200000 n,k200000

分析

完了小号也上紫了(要被迫打div1了
比赛时写了沙雕线段树,比较复杂。
题解给了比较简单的做法。
先求出总共要多少个背包 c n t cnt cnt,再将每个数均匀分配到背包中。
那么 c n t cnt cnt 怎么求呢?
假设大于等于 t t t 的数有 b t b_t bt 个,那么根据抽屉原理,背包个数要大于等于 ⌈ b t c t ⌉ \lceil\frac{b_t}{c_t}\rceil ctbt
所以背包个数就是 c n t = max ⁡ { ⌈ b t c t ⌉ } cnt=\max\{\lceil\frac{b_t}{c_t}\rceil\} cnt=max{ctbt}
接下来怎么构造方案呢?
a i a_i ai 从小到大排序,假设 a i a_i ai t i t_i ti 个。接下来只用把第 i i i 个放进第 i   m o d   c n t i~mod~cnt i mod cnt 个背包即可。因为这样一个背包中 a i a_i ai 的个数不会超过 ⌈ t i c n t ⌉ \lceil\frac{t_i}{cnt}\rceil cntti 个。
复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),其实就是排序的复杂度=。=

代码如下

#include <bits/stdc++.h>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#define N 200005
using namespace __gnu_pbds;
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
struct custom_hash {
	   static uint64_t splitmix64(uint64_t x) {
	   	x += 0x9e3779b97f4a7c15;
		x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
		x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
		return x ^ (x >> 31);
	}
	size_t operator()(uint64_t x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return splitmix64(x + FIXED_RANDOM);
	}
};
LL z = 1;
int read(){
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
	return x * f;
}
int ksm(int a, int b, int p){
	int s = 1;
	while(b){
		if(b & 1) s = z * s * a % p;
		a = z * a * a % p;
		b >>= 1;
	}
	return s;
}
int a[N], c[N], tot, cnt;
vector<int> ans[N];
int main(){
	int i, j, n, k, m;
	n = read(); k = read();
	for(i = 1; i <= n; i++) a[i] = read();
	sort(a + 1, a + i);
	for(i = 1; i <= k; i++) c[i] = read();
	for(i = n; i >= 1; i--) cnt = max(cnt, (n - i) / c[a[i]] + 1);
	for(i = 1; i <= n; i++) ans[i % cnt].push_back(a[i]);
	printf("%d\n", cnt);
	for(i = 0; i < cnt; i++){
		printf("%d ", ans[i].size());
		for(auto x: ans[i]) printf("%d ", x);
		printf("\n");
	}
	return 0;
}

F. Attraction Theory time limit per test2 seconds memory limit per test256 megabytes Taylor Swift - Love Story (Taylor's Version)There are 𝑛 people in positions 𝑝1,𝑝2,…,𝑝𝑛 on a one-dimensional coordinate axis. Initially, 𝑝𝑖=𝑖 for each 1≤𝑖≤𝑛. You can introduce an attraction at some integer coordinate 𝑥 (1≤𝑥≤𝑛), and then all the people will move closer to the attraction to look at it. Formally, if you put an attraction in position 𝑥 (1≤𝑥≤𝑛), the following changes happen for each person 𝑖 (1≤𝑖≤𝑛): if 𝑝𝑖=𝑥, no change; if 𝑝𝑖<𝑥, the person moves in the positive direction, and 𝑝𝑖 is incremented by 1; if 𝑝𝑖>𝑥, the person moves in the negative direction, and 𝑝𝑖 is decremented by 1. You can put attractions any finite number of times, and in any order you want. It can be proven that all positions of a person always stays within the range [1,𝑛], i.e. 1≤𝑝𝑖≤𝑛 at all times. Each position 𝑥 (1≤𝑥≤𝑛), has a value 𝑎𝑥 associated with it. The score of a position array [𝑝1,𝑝2,…,𝑝𝑛], denoted by 𝑠𝑐𝑜𝑟𝑒(𝑝), is ∑𝑛𝑖=1𝑎𝑝𝑖, i.e. your score increases by 𝑎𝑥 for every person standing at 𝑥 in the end. Over all possible distinct position arrays 𝑝 that are possible with placing attractions, find the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝). Since the answer may be large, print it modulo 998244353. Input Each test contains multiple test cases. The first line contains the number of test cases 𝑡 (1≤𝑡≤104). The description of the test cases follows. The first line of each test case contains a single integer 𝑛 (1≤𝑛≤2⋅105). The second line of each test case contains 𝑛 integers — 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109) It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2⋅105. Output For each test case, output a single line containing an integer: the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝) over all possible distinct position arrays 𝑝 that are possible with placing attractions, modulo 998244353. Example inputCopy 7 1 1 2 5 10 3 1 1 1 4 1 1 1 1 4 10 2 9 7 5 1000000000 1000000000 1000000000 1000000000 1000000000 8 100 2 34 59 34 27 5 6 outputCopy 1 45 24 72 480 333572930 69365 Note In the first test case, the only possible result is that person 1 stays at 1. The score of that is 𝑎1=1. In the second test case, the following position arrays [𝑝1,𝑝2] are possible: [1,2], score 15; [1,1], score 10; [2,2], score 20. The sum of scores is 15+10+20=45. In the third test case, the following position arrays [𝑝1,𝑝2,𝑝3] are possible: [1,1,1]; [1,1,2]; [1,2,2]; [1,2,3]; [2,2,2]; [2,2,3]; [2,3,3]; [3,3,3]. Each has a score of 3, and thus the total sum is 24.解决这道,用c++
最新发布
09-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值