题解:CF2053B Outstanding Impressionist

首先观察到对于每个记忆只需满足它是独特的,所以当我们选择一个值时,除了 \(l=r\) 的所有记忆都能躲开它,当 \(l=r\) 时,记录一次 \(l\) 即可。

预处理每个记忆类型到 \(f\) 数组后(题面中限制了 \(1 \le l,r \le 2\times n\)),我们就得到了一个很有前途的 \(O(n^2)\) 做法。

第二层循环枚举的是有无可行的记忆类型,其实可以对 \(f\) 数组做前缀和,检查 \(f_r-f_{l-1}\) 是否为 \(0\),若为 \(0\),说明 \(l\)\(r\) 之间没有一个可行点,输出 \(0\),否则可行,输出 \(1\)

代码不算复杂:

#include<bits/stdc++.h>
using namespace std;
int t, n, a[200005], b[200005], f[400005], now;
map<int, int> mp;
int main(){
	cin >> t;
	while(t --){
		cin >> n;
		mp.clear();
		for(int i = 1; i <= n; i ++) cin >> a[i] >> b[i];
		for(int i = 0; i <= n * 2; i ++) f[i] = 1;//复制为均可
		for(int i = 1; i <= n; i ++){
			if(a[i] == b[i]) mp[a[i]] ++;//此数不可行
		}
		for(int i = 1; i <= 2 * n; i ++){
			if(mp[i]) f[i] = 0;//标记上不可行
		}
		for(int i = 1; i <= 2 * n; i ++) f[i] += f[i - 1];//做前缀和
		for(int i = 1; i <= n; i ++){
			if((a[i] == b[i] && mp[a[i]] == 1) || f[b[i]] - f[a[i] - 1]) cout << 1;//前半部分特判了一下,如果只有它一个只包含 a[i],也是可以的
			else cout << 0;
		}
		cout << "\n";
	}
	return 0;
}

警示后人,\(f\) 数组要开两倍空间,否则 WA on #8。

posted on   zhangzirui66  阅读(85)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示