首页 > 其他分享 >[CF576E] Painting Edges

[CF576E] Painting Edges

时间:2023-11-01 19:13:01浏览次数:44  
标签:CF576E int siz tp read Edges include Painting Find

Painting Edges
动态加边和二分图容易想线段树分治,分别维护 k 种颜色的并查集。
不过每条边的存在时间不能确定。
设边 i 的两次操作的时间为 \(x_i,y_i\),那么对于 \(t\in[x_i+1,y_i-1]\) 有两种情况,颜色改变或改色不变。
则我们把每次操作影响的时间放在树上,从左到右递归到叶子节点判断染色结果即可。
注意不能把 \(x_i\) 放上去,因为这时还不清楚染色是否成功。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<bitset>
using namespace std;
#define db double
#define ll long long
#define ull unsigned long long
#define ld long double
#define ls p<<1
#define rs p<<1|1
#define b1t bitset
#define mkp make_pair
typedef pair<int,int> kk;
const int MAXN=5e5+5;
const int MAXK=55;
const int INF=0x3f3f3f3f;
void read(int &x){
	x=0;int f=1;char s=getchar();
	while(s<'0'||s>'9'){
		if(s=='-') f=-1;s=getchar();
	}
	while(s>='0'&&s<='9'){
		x=(x<<3)+(x<<1)+(s^48);s=getchar();
	}
	x*=f;
}
int n,m,k,q,vva[MAXN],vvb[MAXN],vv[MAXN],va[MAXN],vb[MAXN],c[MAXN],fa[MAXK][MAXN<<1],id[MAXN],siz[MAXK][MAXN<<1],tp;
int Find(int co,int x){return x==fa[co][x]?x:Find(co,fa[co][x]);}
struct SG{
	int l,r;vector<int> ve;
}t[MAXN<<2];
kk ss[MAXN<<1],ff[MAXN<<1];
int cc[MAXN<<1];
void bui(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	bui(ls,l,mid);bui(rs,mid+1,r);	
}
void mer(int c,int x,int y){
	if(x==y) return;
	if(siz[c][x]>siz[c][y]) swap(x,y);
	ss[++tp]=mkp(y,siz[c][y]),ff[tp]=mkp(x,fa[c][x]);cc[tp]=c;
	siz[c][y]+=siz[c][x];fa[c][x]=y;
}
void modi(int p,int l,int r,int x){
	if(t[p].l>=l&&t[p].r<=r){
		t[p].ve.push_back(x);return;
	}
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) modi(ls,l,r,x);
	if(r>mid) modi(rs,l,r,x);
}
void work(int p){
	int op=tp;
	for(auto u:t[p].ve){
		mer(c[u],Find(c[u],va[u]),Find(c[u],vb[u]+n));
		mer(c[u],Find(c[u],va[u]+n),Find(c[u],vb[u]));
	}
	if(t[p].l==t[p].r){
		if(Find(c[t[p].l],va[t[p].l])==Find(c[t[p].l],vb[t[p].l])) c[t[p].l]=id[vv[t[p].l]],printf("NO\n");
		else id[vv[t[p].l]]=c[t[p].l],printf("YES\n");
	}
	else{
		work(ls);work(rs);
	}
	while(tp>op){
		siz[cc[tp]][ss[tp].first]=ss[tp].second;
		fa[cc[tp]][ff[tp].first]=ff[tp].second;
		tp--;
	}
	return;
}
int main(){
	read(n);read(m);read(k);read(q);
	for(int ii=1;ii<=k;ii++){
		for(int i=1;i<=n;i++){
			fa[ii][i]=i;fa[ii][i+n]=i+n;siz[ii][i]=siz[ii][i+n]=1;
		}
	}
	for(int i=1;i<=m;i++){
		read(vva[i]);read(vvb[i]);id[i]=q+1;
	}
	for(int i=1;i<=q;i++){
		read(vv[i]);read(c[i]);va[i]=vva[vv[i]];vb[i]=vvb[vv[i]];
	}
	bui(1,1,q);
	for(int i=q;i>=1;i--){
		if(i+1<id[vv[i]]) modi(1,i+1,id[vv[i]]-1,i);
		id[vv[i]]=i;
	}
	for(int i=1;i<=q;i++) id[i]=0;
	work(1);
	return 0;
}

标签:CF576E,int,siz,tp,read,Edges,include,Painting,Find
From: https://www.cnblogs.com/StranGePants/p/17803856.html

相关文章

  • CF1479B1 Painting the Array I
    如果两种方案末尾两数有一数相同,那么答案较大的方案不劣于答案较小的方案。答案较大的方案只需\textbf{模仿}答案较小的方案即可,在状态变成相同之前答案最多只会少\(1\)。所以只需要考虑末尾两数\(a,b\)与新进来的数\(c\)各不相同时该替换哪个。假设\(a\)下次出现的位置......
  • 2023-10-04:用go语言,现有一棵无向、无根的树,树中有 n 个节点,按从 0 到 n - 1 编号 给你
    2023-10-04:用go语言,现有一棵无向、无根的树,树中有n个节点,按从0到n-1编号给你一个整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间存在一条边。每个节点都关联一个价格。给你一个整数数组price,其中price[i]是第i......
  • Educational Codeforces Round 152 (Div. 2) D. Array Painting(双指针)
    EducationalCodeforcesRound152(Div.2)D.ArrayPainting//思路:双指针找连续正数段//若段中出现2,则更新两头的0的情况,若为涂色则改为true//若无2,则优先更新左侧0,若左0已经为true,则更新右侧0//数组开头结尾特判#defineintlonglong#defineldlongdoubleusingnam......
  • 2023-10-04:用go语言,现有一棵无向、无根的树,树中有 n 个节点,按从 0 到 n - 1 编号 给你
    2023-10-04:用go语言,现有一棵无向、无根的树,树中有n个节点,按从0到n-1编号给你一个整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间存在一条边。每个节点都关联一个价格。给你一个整数数组price,其中price[i]是第i......
  • 2023-10-04:用go语言,现有一棵无向、无根的树,树中有 n 个节点,按从 0 到 n - 1 编号 给你
    2023-10-04:用go语言,现有一棵无向、无根的树,树中有n个节点,按从0到n-1编号给你一个整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间存在一条边。每个节点都关联一个价格。给你一个整数数组price,其中price[i]是......
  • 2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数
    2023-09-03:用go语言编写。给你一个n个节点的无向无根树,节点编号从0到n-1给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间有一条边。再给你一个长度为n的数组coins,其中coins[i]可能为0也可能为1,1表示节......
  • 2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数
    2023-09-03:用go语言编写。给你一个n个节点的无向无根树,节点编号从0到n-1给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间有一条边。再给你一个长度为n的数组coins,其中coins[i]可能为0也可能为1,1......
  • Lnton羚通算法算力云平台在OpenCV-Python中如何图像修复 Image Inpainting
    OpenCVPython图像修复【理论】大多数人家里都会有一些旧照片,上面有一些黑点,一些笔画等。你想过把它修复回来吗?我们不能简单地在油漆工具中删除它们,因为它只会用白色结构取代黑色结构,这是没有用的。在这些情况下,使用一种称为图像修补的技术。基本的想法很简单:用邻近的像素替换......
  • CFgym103260K-Rectangle Painting
    前言断续地调了一天一夜,终于做出来了!题目链接-RectanglePainting大概就是:给\(n\)个集合\(S_i\),两种操作,1{[l,r],x}lr向\(S_l\)到\(S_r\)插入\(x\)2lr询问\(\max\limits_{i=l}^r\{\text{mex}(S_i)\}\)。但是强制在线!\(1\len,l,r\le2\times10^5,1\le......
  • 洛谷_[P4084]Barn Painting G题解
    题目链接这题我们可以定义一个二维的dp数组,在dp[i][j]中:i表示对于节点i,j有1,2,3三种状态,表示当点i选择被染成颜色j时,以i为根的这颗子树有多少种染色方法。那么根据乘法原理,节点i的方案数肯定等于i的每个儿子的方案数量之积。这道题整个挺简单的,剩下细节......