首页 > 其他分享 >CF1764H Doremy's Paint 2 题解

CF1764H Doremy's Paint 2 题解

时间:2023-12-11 17:00:39浏览次数:35  
标签:include int 题解 Doremy ch CF1764H ans 操作 inter

题目链接

先断环成链,由于对于多组询问不好一起处理,我们先考虑单组询问的处理方式。

一个很暴力的想法是每次模拟题目要求的操作并且最后数颜色,我们这是在通过下标进行操作最后再数颜色,而很多对于下标的操作都是不必要的,考虑直接枚举颜色进行判定。

对于每种颜色,它对于最后答案有贡献当且仅当它可以存活到那个时刻,即每次延伸出去的点都没有被后来的操作所覆盖。

考虑刻画这个“没有被覆盖”的条件,由于该颜色区间的左右边界一定单调移动,一个想法是正着考虑,每次维护当前颜色所在区间的左右端点,每次操作对若干区间进行处理,但是这种做法比较不好维护且扩展性较差。

再转换一下思路,注意到一个颜色能存活其实等价于自己存活或者延伸出去的节点能存活,而延伸出去的节点和自己存活的时间都会在后面进行计算,我们考虑倒着进行操作。

记 \(t_i\) 表示第 \(i\) 个节点及其延伸最后一次被覆盖的时间(注意到这里是第 \(i\) 个节点及其延伸,我们不考虑的前面与它相同的节点),第 \(k\) 每次操作相当于:

\[i\in[l+1,r],t_i\leftarrow k \]

\[t_l \leftarrow \max_{j\in [l+1,r]} t_j \]

初始时 \(t_i=\infty\),我们倒着进行所有的操作,第 \(x\) 个时刻开始的答案就等价于 \(t_i>x+k-1\) 的位置个数,而这个做法推广到多组询问也是容易的。

最后一个问题是我们如何快速维护上述操作,由于这里有推平操作,我们考虑维护 \(t\) 相等的连续段并尝试证明复杂度,注意到一开始 \(t\) 相同的连续段有 \(n\) 个,每次遍历连续段的同时也是在推平,每次新建的连续段也是 \(O(1)\) 的,也就是说遍历的连续段总数就是 \(O(n)\) 的。

因此,我们只要用 set 维护连续段,树状数组维护数点,即可完成此题,时间复杂度 \(O(n \log n)\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
#define itt set<inter>::iterator 
#define N 500005
using namespace std;
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='-' && ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
void write(int x){
	if(x/10)write(x/10);
	putchar(x%10+'0');
}
struct BIT{
	int a[N];
	int lowbit(int x){return x&(-x);}
	void add(int x,int val){while(x<N){a[x]+=val;x+=lowbit(x);}}
	int ask(int x){int ans=0;while(x){ans+=a[x];x-=lowbit(x);}return ans;}
}T;
int l[N],r[N],an[N];
struct inter{
	int l,r,val;
	inter(int l,int r,int val):l(l),r(r),val(val){}
};
bool operator <(inter x,inter y){
	return (x.l==y.l?x.l<y.l:x.r<y.r);
}
set<inter> t;
void split(int x){
	itt it=t.lower_bound(inter(x,x,0));
	if(it==t.end() || (it->l)>x)it--;
	if(it->r==x)return;
	int tl=it->l,tr=it->r,tval=it->val;
	t.erase(it);t.insert(inter(tl,x,tval));t.insert(inter(x+1,tr,tval));
}
int main(){
	int n=read(),m=read(),k=read();
	for(int i=1;i<=m;i++)l[i]=read(),r[i]=read();
	for(int i=m+1;i<=m+k-1;i++)l[i]=l[i-m],r[i]=r[i-m];
	for(int i=1;i<=n;i++)t.insert(inter(i,i,N-1)),T.add(N-1,1);
	for(int i=m+k-1;i>=1;i--){
		split(l[i]-1);split(r[i]);
		itt it=t.lower_bound(inter(l[i],l[i],0)),itl=it;
		int ans=it->val;
		for(;it!=t.end() && (it->r)<=r[i];it++){
			int siz=(it->r)-(it->l)+1;T.add(it->val,-siz);
			ans=max(ans,it->val);
		}
		t.erase(itl,it);
		t.insert(inter(l[i],l[i],ans));T.add(ans,1);
		if(r[i]>l[i])t.insert(inter(l[i]+1,r[i],i)),T.add(i,r[i]-l[i]);
		if(i<=m)an[i]=T.ask(N-1)-T.ask(i+k-1);
	}
	for(int i=1;i<=m;i++)write(an[i]),putchar(' ');
}

标签:include,int,题解,Doremy,ch,CF1764H,ans,操作,inter
From: https://www.cnblogs.com/eastcloud/p/17894819.html

相关文章

  • UVA1658 Admiral 题解
    LinkUVA1658AdmiralQuestion给出一个图,找出\(1\simn\)的两条,使得路径和最小Solution可以把点拆开,把除了\(1\)和\(n\)的点\(i\),拆成\(i\)和\(i'\),\(i\)到\(i'\)连一条费用为\(0\),容量为\(1\)的边,如果原来有一条边\(u-v\),那么就建立一条\(u'->v\),费......
  • P2341 受欢迎的牛 G 题解
    LinkP2341[USACO03FALL/HAOI2006]受欢迎的牛GQuestion牛栏中有\(N\)头奶牛,和一些\(M\)对爱慕关系,A->B表示A爱慕B。每个奶牛都喜欢自己,被所有奶牛喜欢就是一头明星奶牛,求明星奶牛的数量Solution考虑一个强连通分量里面的奶牛是相互爱慕的,先根据强连通分量缩点,缩......
  • 题解 QOJ1173【Knowledge Is...】 / accoders::NOI 5681【interval】
    https://qoj.ac/contest/537/problem/1173problem给定\(n\leq10^6\)个区间,你需要求出能够最多选出多少对区间,使得两个区间不交(区间为闭区间)。要求一个区间最多属于一对选出的区间。solution这是一般图匹配问题的特殊情况,所以放弃dp,考虑贪心、网络流、匹配等。按照左端点......
  • P5048 [Ynoi2019 模拟赛] 题解
    题意给定\(n\)个数,有\(m\)个询问,每个询问给定\(l\)和\(r\),求出区间\(l\)到\(r\)中的最小众数出现次数,强制在线。数据范围:\(n\le500000\),空间限制:\(62.5MB\)。思路这道题的弱化版是蒲公英,这道题加强的地方在于数据范围。正常的分块求区间众数的空间复杂度是\(O(n......
  • CF1842E Tenzing and Triangle 题解
    题意不多赘述。思路如果两个所选的三角形有重合部分的话,那么这种情况肯定是不会出现的。因为如果把这两个三角形合成一个大三角形的话,不仅覆盖面积会增大,而且花费的代价还不会多。于是我们可以想到用dp来解决,设\(dp_{i}\)表示删完横坐标为\(0\)到\(i\)中的点的最小代价......
  • [ABC304Ex] Constrained Topological Sort 题解
    题意给定一张有向图\(G\),有\(n\)个点和\(m\)条边,问是否存在一种拓扑序的排列\(P\)使得\(l_{i}\lep_{i}\ler_{i}\)。思路首先对于一条边\(u\tov\),如果限制满足\(r_{v}\ler_{u}\)或者\(l_{v}\gel_{u}\)的话,那么这个限制其实是不完全正确的。因为最终的序列......
  • 【题解】AtCoder abc322_f Random Update Query
    传送门:https://atcoder.jp/contests/abc332/tasks/abc332_f容易发现,对于一个位置$i$,$A_i$的最终值是由对$i$的最后一次赋值操作决定的;因此,将所有操作按时间顺序倒过来考虑,则由第$j$次操作决定$A_i$最终值的概率为"在第$(j+1)$~$m$次操作中没有修改过$i$的概率"与"第......
  • 【题解】AtCoder abc332_g Not Too Many Balls
    传送门:https://atcoder.jp/contests/abc332/tasks/abc332_g看完题,第一眼反应为最大流。建模方式为:以颜色为左部点,盒子为右部点,源点$S$向颜色$i$连一条容量为$A_i$的边,盒子$j$向汇点$T$连一条容量为$B_j$的边,颜色$i$向盒子$j$连一条容量为$ij$的边;在这张图......
  • AT_cf17_final_j Tree MST 题解
    题意:给定一颗\(n\)个点的树,点\(i\)有权值\(a_{i}\),边有边权。现在有另外一个完全图,两点之间的边权为树上两点之间的距离加上树上两点的点权,求这张完全图的最小生成树。首先有一个很显然的暴力,把完全图中每两点之间的边权算出来,然后跑一边最小生成树,时间复杂度\(O(n^{2}\lo......
  • P7735 [NOI2021] 轻重边 题解
    是一道树剖好题,之前听lsl讲过一点,于是很快就做出来了。题意:有一个\(n\)个节点的树,最开始的时候所有边都是轻边,维护两个操作:操作一:将\(u\)到\(v\)的路径中经过的所有点的邻边变为轻边,再将这条路径上的边变为重边。操作二:求出\(u\)到\(v\)这条路径上有多少条重边......