【无标题】

本文介绍了Codeforces Round #806 (Div. 4)的比赛题目,重点分析了D、E、F三道模拟题的解题思路。D题通过预处理和枚举实现;E题涉及矩阵的最小区间修改次数计算,易犯错误需注意;F题提出了一种线性时间复杂度的解决方案,涉及后缀数组的概念。博客作者分享了编程竞赛中的常见误区,并提供了关键代码片段。
摘要由CSDN通过智能技术生成

Codeforces Round #806 (Div. 4)

难道更好吗的阅读体验

A B C

模拟题,三道 *800。

D

用一个 map 记录这 n n n 个字符串存在过。然后对于每个字符串,枚举字符串的 ( n − 1 ) (n-1) (n1) 种剖分 left + right \text{left + right} left + right

如果 left \text {left} left right \text{right} right 都存在于我们预处理的 map 之中,那么输出 1 1 1 结束。如果始终没有输出 1 1 1,输出 0 0 0 即可。

复杂度 Θ ( ∑ ∣ s ∣ ) \Theta (\sum|s|) Θ(s)

E

记录对于所有 1 ≤ i ≤ ⌊ n + 1 2 ⌋ , 1 ≤ j ≤ ⌊ n 2 ⌋ 1\leq i \leq \lfloor\frac{n+1}{2}\rfloor,1\leq j \leq \lfloor\frac{n}{2}\rfloor 1i2n+1,1j2n a i , j , a j , n + 1 − i , a n + 1 − i , n + 1 − j , a n + 1 − j , i a_{i,j},a_{j,n+1-i},a_{n+1-i,n+1-j},a_{n+1-j,i} ai,j,aj,n+1i,an+1i,n+1j,an+1j,i 中最小的更改次数使得 a i , j = a j , n + 1 − i = a n + 1 − i , n + 1 − j = a n + 1 − j , i a_{i,j}=a_{j,n+1-i}=a_{n+1-i,n+1-j}=a_{n+1-j,i} ai,j=aj,n+1i=an+1i,n+1j=an+1j,i

考场上的 9 \sqrt{\text{9}} 9 个弱智错误导致最后摆烂:

  • 没看题,第一次做法假了。
  • a i , j , a j , n + 1 − i , a n + 1 − i , n + 1 − j , a n + 1 − j , i a_{i,j},a_{j,n+1-i},a_{n+1-i,n+1-j},a_{n+1-j,i} ai,j,aj,n+1i,an+1i,n+1j,an+1j,i 的下标搞错
  • 输入用了 bool,其实是 char(我怎么不看题啊喂)

F

标算 Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn),我只能说 Θ ( n ) \Theta(n) Θ(n) 更好想。(

一眼题。首先有一个空的容器用于记录所有满足 a x < x a_x<x ax<x(即 v a l < p o s val<pos val<pos) 的 ( v a l , p o s ) (val,pos) (val,pos),这样我们只需要找到满足 i < a j i<a_j i<aj ( i , j ) (i,j) (i,j) 数量了。

Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn) 的话可以直接排序,然后每次二分就好了。

但是因为容器里的 ( v a l , p o s ) (val,pos) (val,pos) 值都不可能大于 n n n,所以我们用一个 m i m_i mi 记录 i i i 在所有 v a l val val 中出现的次数, p i p_i pi 记录大于等于 i i i 的所有 p o s pos pos 数量。

m m m 可以直接 Θ ( n ) \Theta(n) Θ(n) 记录。

p p p 显然是一个后缀数组,满足递推式 p i = p i + 1 + m i + 1 , p n + 1 = 0 p_i=p_{i+1}+m_{i+1}, p_{n+1}=0 pi=pi+1+mi+1,pn+1=0

因为是大于等于,所以大于就是 p p o s + 1 p_{pos+1} ppos+1

因而,最后计算 ∑ p p o s + 1 \sum p_{pos+1} ppos+1 即可。

我讲的可能有点乱,结合代码看看

int m[200005], p[200005];
int solve() {
	int n = read<int>(); 
	memset(m, 0, sizeof(m));
	vector<pair<int, int> > v;
	rep(i, 1, n) {
		int x; cin >> x;
		if(x < i) {
			v.push_back({x, i});
			m[x]++;
		}
	}
	p[n + 1] = 0;
	p[n] = m[n];
	irep(i, 0, n - 1) p[i] = p[i + 1] + m[i];
	int ans = 0;
	for(int i = 0; i < v.size(); i++) {
		ans += p[v[i].second + 1];
	}
	cout << ans << endl;
	return 114514;
}

G

没看。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值