首页 > 其他分享 >P11024 [COTS 2020] 定序 Redoslijed 题解

P11024 [COTS 2020] 定序 Redoslijed 题解

时间:2024-12-01 16:34:02浏览次数:9  
标签:cnt 定序 COTS 标记 题解 合法 ch text 操作

先把是否有色的约束处理掉。累一个前缀和,对每个位置判一下即可。

考察区间覆盖的性质,显然最后一个操作的区间内的颜色一定与其覆盖的颜色相同。考虑从后往前确定操作的顺序,一个操作只要满足这个条件就可以作为当前的最后一个操作,如果有多个满足条件的操作,随便取一个都合法。

考虑维护满足条件的操作,每次取出一个操作将其区间内的位置标记掉,将所有从不合法变为合法的操作加入集合。

如何快速求出从不合法变为合法的操作?有个经典的套路就是用线段树将每个区间拆成若干段,对每个操作记录不合法的段数 \(\text{cnt}_i\)。每次区间标记在线段树上递归找到所有需要标记的点,因为每个点只会被标记一次,所以时间复杂度是一个 \(\log\)。

观察什么时候需要将一些操作的 \(\text{cnt}\) 减一。发现当线段树上的一个点对应区间内的颜色数从 \(>1\) 变成 \(1\) 时,需要将含有这个点且颜色与剩下的这个颜色相同的操作的 \(\text{cnt}\) 减一,对每个点记录颜色 \(\min,\max\) 即可判断。当一个点被完全标记掉时将包含它的剩下操作的 \(\text{cnt}\) 减一。\(\text{cnt}\) 减到 \(0\) 时加入集合即可。

然后就做完了,时间复杂度 \(\mathcal O((N+M) \log N)\),参考代码:

#include<bits/stdc++.h>
#define mxn 500003
#define pb push_back
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rept(i,a,b) for(int i=(a);i<(b);++i)
#define drep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
struct node{
	int l,r,c;
}d[mxn];
int n,m,tt,tot,a[mxn],c[mxn],ct[mxn],st[mxn],ans[mxn],t1[mxn<<2],t2[mxn<<2],cl[mxn<<2];
vector<int>t[mxn<<2];
bool b[mxn<<2],b1[mxn<<2];
void build(int p,int l,int r){
	if(l==r){
		if(a[l])t1[p]=t2[p]=a[l],b1[p]=1;
		else t1[p]=1e9,t2[p]=-1e9,b[p]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t1[p]=min(t1[p<<1],t1[p<<1|1]);
	t2[p]=max(t2[p<<1],t2[p<<1|1]);
	b1[p]=t1[p]==t2[p],b[p]=t2[p]<0;
}
void add(int p,int l,int r,int x,int L,int R){
	if(l<=L&&R<=r){
		if(b1[p]&&t1[p]==d[x].c)return;
		ct[x]++,t[p].pb(x);
		return;
	}
	int mid=(L+R)>>1;
	if(l<=mid)add(p<<1,l,r,x,L,mid);
	if(r>mid)add(p<<1|1,l,r,x,mid+1,R);
}
void upd(int p,int l,int r,int L,int R){
	if(b[p])return;
	if(L==R){
		b[p]=1,t1[p]=1e9,t2[p]=-1e9;
		for(int i:t[p])if(d[i].c!=cl[p]){
			if(!(--ct[i]))st[++tot]=i;
		}
		return;
	}
	int mid=(L+R)>>1;
	if(l<=mid)upd(p<<1,l,r,L,mid);
	if(r>mid)upd(p<<1|1,l,r,mid+1,R);
	t1[p]=min(t1[p<<1],t1[p<<1|1]);
	t2[p]=max(t2[p<<1],t2[p<<1|1]);
	if(t2[p]<0&&!b[p]){
		b[p]=1;
		for(int i:t[p])if(d[i].c!=cl[p]){
			if(!(--ct[i]))st[++tot]=i;
		}
	}else if(t1[p]==t2[p]&&!b1[p]){
		cl[p]=t1[p],b1[p]=1;
		for(int i:t[p])if(d[i].c==cl[p]){
			if(!(--ct[i]))st[++tot]=i;
		}
	}
}
signed main(){
	n=read(),m=read();
	rep(i,1,m)d[i].l=read(),d[i].r=read(),d[i].c=read(),c[d[i].l]++,c[d[i].r+1]--;
	rep(i,1,n){
		a[i]=read();
		c[i]+=c[i-1];
		if((c[i]&&!a[i])||(!c[i]&&a[i])){
			puts("NE");
			return 0;
		}
	}
	build(1,1,n);
	rep(i,1,m)add(1,d[i].l,d[i].r,i,1,n);
	rep(i,1,m)if(!ct[i])st[++tot]=i;
	while(tot){
		int x=st[tot--];ans[++tt]=x;
		upd(1,d[x].l,d[x].r,1,n);
	}
	if(tt!=m)puts("NE");
	else{
		puts("DA");
		drep(i,m,1)cout<<ans[i]<<" ";
	}
	return 0;
}

标签:cnt,定序,COTS,标记,题解,合法,ch,text,操作
From: https://www.cnblogs.com/zifanoi/p/18579883

相关文章

  • 【题解】ABC382D Keep Distance
    题目描述你需要求出所有长度为\(n\),且满足以下条件的序列的个数,并按照字典序输出:首项大于等于\(1\),每一项比前一项至少大\(10\),最后一项小于等于\(m\)。题目分析爆搜,用vector存储答案和个数,输出。代码实现#include<iostream>#include<algorithm>#include<vector......
  • 洛谷P1880 [NOI1995] 石子合并 题解
    此题解以纪念我终于差不多大概搞懂区间dp了(插个存档点,到时候忘了再回来看看)。P1880[NOI1995]石子合并题解在做这道题之前,可以看看P1775石子合并(弱化版)(一道题解帮你搞定两道题,多划算)。P1775石子合并(弱化版)形式化的题面一堆石头摆在你面前,让你把他们扔到一起,每次扔......
  • 【Q1~Q6题解】第七届传智杯全国IT技能大赛-程序设计赛道第一场院校赛(初赛)思路+解题代
    本文为作者的题解解析。Q1~Q6,思路仅供参考文章目录Q1:汤姆和杰瑞解题代码解题思路Q2:游游的重组偶数解题代码解题思路Q3:小红的四子棋解题代码解题思路Q4:小欧的平面连线解题代码解题思路Q5:小红的数组操作解题代码解题思路Q6:游......
  • 国产化硬件系统上,部署视频监控平台系统软件出现的脚本问题解决
    目录一、问题描述二、解决方法        1、检查部署脚本权限        2、检查脚本中语法是否有问题        3、使用tee命令对文件进行修改        4、查看银河麒麟系统的安全设置        在国产系统银河麒麟硬件设备上部署视频......
  • P1135 奇怪的电梯 JAVA题解
    题目描述呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 ii 层楼(1≤i≤N1≤i≤N)上有一个数字 KiKi​(0≤Ki≤N0≤Ki​≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例......
  • P2658 汽车拉力比赛 JAVA题解
    package篮桥杯.d;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.StreamTokenizer;importjava.util.LinkedList;importjava.util.Queue;publicclassMain{//自定义的输入类,比普通Scanner快两......
  • USB无法识别设备?USB驱动问题解析篇
    今天我们来讲解的是USB驱动问题,连接USB无法识别模组设备,是不是驱动问题?今天就一起来聊聊如何排查解决。注意:本文涉及的内容都是基于Windows系统,且不低于Win7版本;Linux/Mac/UNIX/低版本的Windows,不在本文涉及范围之内。一、哪些模组需要安装USB驱动可根据下方分类判断自己手中的......
  • Atcoder Beginner Contest 330 题解
    前言过于水的一场。ACountingPasses题面给出一个长度为\(n\)的序列\(a\),求出\(a\)之中大于等于\(l\)的数个个数。\(1\len\le100,1\lea_i\le1000,1\lel\le1000\)。制約入力は全て整数$1\\le\N\\le\100$$1\\le\L\\le\1000$$0\\le\A_i\\le......
  • 读数据质量管理:数据可靠性与数据质量问题解决之道19数据未来
    1. 开创可靠数据系统的未来1.1. 数据作为一个行业很可能正在经历一场巨大且不可逆转的巨变1.2. 分析型数据正变成现代企业最关键和最具竞争力的核心资产1.2.1. 不再是公司是否依赖数据的问题1.2.2. 是使用多少数据以及将数据用于什么场景的问题1.3. 仅仅收集更......
  • 题解:AT_abc018_4 [ABC018D] バレンタインデー
    暴力搜索当我们发现u很小时,就可以直接暴搜。但我们该怎么搜索呢?因为是教师送给学生礼物,所以我们先搜索老师,记录下来当前这个老师选还是不选。当我们选完了p个老师,学生部分就可以直接算分数。先枚举每一个老师,如果当前老师选上了,就去枚举学生,在当前这个学生的贡献中加上幸......