专栏文章

题解:CF2053B Outstanding Impressionist

CF2053B题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqmme4o
此快照首次捕获于
2025/12/04 07:16
3 个月前
此快照最后确认于
2025/12/04 07:16
3 个月前
查看原文

CF2053B Outstanding Impressionist

分析

对于第 ii 个位置,我们可以选择将其设置为 [li,ri][l_i,r_i] 区间中的任意一个数字,我们想要让其他的位置都不设置为当前位置 ii 设置的数,看是否可行。
显然,当前位置 ii 不可行当且仅当 [li,ri][l_i,r_i] 中的每一个数字,都有至少一个其他的位置必须填;即 j[li,ri]\forall j \in [l_i,r_i],存在一个位置 kk,满足 1kn,ki,lk=rk=j1 \leq k \leq n,k \neq i,l_k=r_k=j
然后我们对于每一个形如 lx=rxl_x=r_x 的限制进行标记,令 d[lx]=1d[l_x]=1,令 c[lx]c[l_x] 自增 11,然后前缀和处理就能在后面对于每一个位置的取值区间 O(1)O(1) 地来判断区间中的数字是否都被其他位置必须填。特别地,若某一个位置 ii 满足 li=ril_i=r_i,则特殊处理,判断 c[li]c[l_i] 是否大于等于 22 即可。
记得数组用多少清多少,不要使用 memset。
代码是赛时写的,有点丑,见谅。

AC CODE

CPP
#include<bits/stdc++.h>
using namespace std;
int t;
int n,a[200005],b[200005],c[500005],d[500005];
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		int mx=0;
		for(int i=0;i<=2*n;i++){
			c[i]=0;
			d[i]=0;
		} 
		for(int i=1;i<=n;i++){
			cin>>a[i]>>b[i];
			if(a[i]==b[i]){
				d[a[i]]=1;
				c[a[i]]++;
				mx=max(mx,a[i]);
			}
		}
		for(int i=1;i<=mx;i++){
			c[i]=c[i-1]+c[i];
			d[i]=d[i-1]+d[i];
		}
		for(int i=1;i<=n;i++){
			if((a[i]!=b[i]&&d[b[i]]-d[a[i]-1]>=b[i]-a[i]+1)||(a[i]==b[i]&&c[b[i]]-c[a[i]-1]-1>=b[i]-a[i]+1)) cout<<0;
			else cout<<1;
		}
		puts("");
	}
	return 0;
} 

评论

0 条评论,欢迎与作者交流。

正在加载评论...