【考后】CSP-S模拟9

我要再这么颓下去就无了。

A. \(\color{black}{\textrm{LIS to Original Sequence}}\)

题解

就是构造。

怎么构造?

这么构造!

先插入 \(a_i\) ,再插入一个小于 \(a_i\) 且在没有取过的数字中最小的数 \(\left(i \in \left[1,k\right)\right)\) 。(如果没有则跳过)

最后把剩下的数倒序输出。

显然,我们保证了序列 \(A\) 是我们构造的 \(P\) 的一个 \(\texttt{LIS}\)

其实字典序最小也是比较显然的,因为每次都插入了最小的数,并且不能再插入一个第二小的数了,否则 \(\texttt{LIS}\) 就变了。

#include <iostream>
const int N = 2e5+10;
int n, k;
int buf[N];
int a;
int main() {
	scanf("%d %d",&n,&k);
	register int j = 1;
	for(register int i = 1;i < k;++i) {
		scanf("%d",&a);
		printf("%d ",a);
		buf[a] = true;
		while(buf[j]) 
			++j;
		if(j < a) {
			printf("%d ",j);
			buf[j] = true;
			while(buf[j]) 
				++j;
		}
	}
	for(register int i = n;i >= j;--i) 
		if(!buf[i]) 
			printf("%d ",i);
	putchar(10);
	return 0;
}

B. \(\color{black}{\textrm{Unique Subsequence}}\)

题解

每次如果数 \(a_i\) 第一次出现,就正常转移 : \(dp_i = \sum\limits_{j = 1}^{i-1}dp_{j}+1\)

否则只从 \(prev_{a_i} \sim i-1\) 转移,并删去 \(prev_{a_i}\)

#include <iostream>
const int moyn = 998244353;
const int N = 2e5+10;
int n;
int tree[N];
void modify(int pos,int val) {
	for(;pos <= n;pos += pos&-pos) {
		tree[pos] = tree[pos]+val;
		if(tree[pos] >= moyn) 
			tree[pos] -= moyn;
	}
}
int query(int pos) {
	int res = 0;
	for(;pos;pos -= pos&-pos) {
		res += tree[pos];
		if(res >= moyn) 
			res -= moyn;
	}
	return res;
}
int buf[N];
int val[N];
int ans;
int main() {
	scanf("%d",&n);
	for(register int i = 1;i <= n;++i) {
		int a, f;
		scanf("%d",&a);
		if(buf[a]) {
			f = ans-query(buf[a]-1)+moyn;
			if(f >= moyn) 
				f -= moyn;
			modify(buf[a],moyn-val[a]);
			ans = (ans-val[a]+moyn);
			if(ans >= moyn) 
				ans -= moyn;
		} else 
			f = ans+1;
		modify(i,f);
		ans += f;
		if(ans >= moyn) 
			ans -= moyn;
		buf[a] = i;
		val[a] = f;
	}
	printf("%d\n",ans);
	return 0;
}

C. \(\color{black}{\textrm{Maximize GCD}}\)

题解

挺好搞的。

  1. \(k\) 可以使所有值达到 \(\max\left\{a\right\}\)\(ans = \max\left\{a\right\}+\left\lfloor\dfrac{k-\sum_{i = 1}^{{{n}}}\max\left\{a\right\}-a_i}{n}\right\rfloor\)

  2. 否则枚举每一个 \(x \in \left(1,\max\{a\}\right)\) ,发现当且仅当 \(\sum\limits_{i = 1}^{n}x-a_i \bmod x \le k\) 时成立。于是可以每 \(\left(k\cdot x,(k+1)\cdot x\right]\;,\;\left(k \in \left[0,\frac{\max\{a\}}{x}\right]\right)\) 一组进行求解。

#include <iostream>
#include <random>
#define llt long long int
const int N = 3e5+10;
llt n, ans = 1;
llt a[N], k, del_sum;
llt max_a = 0;
llt buf_pre[N], sum_pre[N];
int main() {
	scanf("%lld%lld",&n,&k);
	for(register int i = 1;i <= n;++i) {
		scanf("%lld",&a[i]);
		if(a[i] > max_a) 
			max_a = a[i];
		++buf_pre[a[i]];
		sum_pre[i] += (llt)a[i];
	}
	for(register int i = 1;i <= n;++i) 
		del_sum += max_a-a[i];
	if(k >= del_sum) {
		std :: cerr << "here\n";
		printf("%lld\n",max_a+(k-del_sum)/n);
	} else {
		for(register int i = 1;i < N;++i) {
			sum_pre[i] += sum_pre[i-1];
			buf_pre[i] += buf_pre[i-1];
		}
		// std :: cerr << k << std :: endl;
		for(register int i = 2;i < N;++i) {
			llt l = 1LL;
			llt r = (llt)i;
			llt res = 0LL;
			while(l < N) {
				llt tmp_1 = buf_pre[std :: min(r,N-1LL)]-buf_pre[l-1];
				llt tmp_2 = sum_pre[std :: min(r,N-1LL)]-sum_pre[l-1];
				res += r*tmp_1-tmp_2;
				l += i;
				r += i;
			}
			if(res <= k) 
				ans = i;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

D. \(\color{black}{\textrm{Pure Straight}}\)

题解

咕咕咕

#include <iostream>
#include <cstring>
int n, k, m;
int a[201];
int dp[1<<16];
int main() {
	scanf("%d %d",&n,&k);
	for(register int i = 1;i <= n;++i) 
		scanf("%d",&a[i]);
	m = (k+1)>>1;
	memset(dp+1,0x3f,((1<<k)-1)*sizeof(int));
	for(register int i = 1;i <= n;++i) 
		for(register int j = (1<<k)-1;~j;--j) {
			if(!((j>>(a[i]-1))&1)) 
				continue;
			int true_counter = __builtin_popcount(j);
			int del_nowbit = j^(1<<(a[i]-1));
			int upper_counter = __builtin_popcount(j>>a[i]);
			if(true_counter < m) 
				dp[j] = std :: min(dp[j],dp[del_nowbit]+upper_counter-i+true_counter-m);
			else if(true_counter > m) 
				dp[j] = std :: min(dp[j],dp[del_nowbit]+upper_counter+i-true_counter+m);
			else 
				dp[j] = std :: min(dp[j],dp[del_nowbit]+upper_counter+(k&1 ? 0 : -1)*i);
		}
	printf("%d\n",dp[(1<<k)-1]);
	return 0;
}
posted @ 2022-09-22 19:17  bikuhiku  阅读(32)  评论(0编辑  收藏  举报