首页 > 其他分享 >P10572 [JRKSJ R8] +1-1 题解

P10572 [JRKSJ R8] +1-1 题解

时间:2024-06-10 19:34:03浏览次数:25  
标签:... ch 题解 查集 R8 P10572 路径 rightarrow

样例给了我们一个很好的提示。观察样例中 \(1\rightarrow 4\) 的路径,发现 \(4 \rightarrow 5\) 这条边走了两遍,再结合题目描述中不需要保证是简单路径的提示,我们发现:

如果路径两侧分别是 ( \(\rightarrow\) () \(\rightarrow\) ) 的话,那么中间不管怎么走都可以通过左右横跳来调整成一个合法的括号序列。

总结一下是合法括号序列的条件:

  • 首先起点要是 ( ,终点要是 ) ,且二者之间有长为偶数的路径(如果你知道并查集维护二分图的技巧,那这就很简单了)
  • 能够通过 ()()()()()... 的形式直接到达。可以使用并查集维护。
  • 起点能够 ()()... 地到达一个 ( \(\rightarrow\) ( 的边,终点反之,也可以用并查集维护。

写一大堆并查集即可。

\(upd:\) 一开始写的时候没有注意,由于图可能不连通,所以要对每一个连通块分别判一次奇环。

代码

#include<bits/stdc++.h>
using namespace std;
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	char ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);
}
const int N=5e5+5;
int n,m,q,v[N];
struct Edge{
	int x,y;
}e[N];
int fa[N<<1],fa1[N],fa2[N],fa3[N];
int tag1[N],tag2[N],jh[N];
inline int fd(int *fa,int x){
	if(fa[x]==x)return x;
	return fa[x]=fd(fa,fa[x]);
}
int ans[N];
string s;
signed main(){
	rd(n,m,q);
	cin>>s;
	for(int i=0;i<n;i++){
		if(s[i]=='('){
			v[i+1]=1;
		}else v[i+1]=-1;
	}
	for(int i=1;i<=n;i++)fa1[i]=fa2[i]=fa3[i]=i;
	for(int i=1;i<=n*2;i++)fa[i]=i;
	for(int i=1;i<=m;i++){
		rd(e[i].x,e[i].y);
		int x=e[i].x,y=e[i].y;
		if(fd(fa,x)!=fd(fa,y+n))fa[fd(fa,x)]=fd(fa,y+n);
		if(fd(fa,y)!=fd(fa,x+n))fa[fd(fa,y)]=fd(fa,x+n);
		if(!(v[x]==-1&&v[y]==-1))
			if(fd(fa1,x)!=fd(fa1,y))fa1[fd(fa1,x)]=fd(fa1,y);
		if(!(v[x]==1&&v[y]==1))
			if(fd(fa2,x)!=fd(fa2,y))fa2[fd(fa2,x)]=fd(fa2,y);
		if(!(v[x]==-1&&v[y]==-1)&&!(v[x]==1&&v[y]==1))
			if(fd(fa3,x)!=fd(fa3,y))fa3[fd(fa3,x)]=fd(fa3,y);
	}
	for(int i=1;i<=m;i++){
		int x=e[i].x,y=e[i].y;
		if(fd(fa,x)==fd(fa,x+n))jh[fd(fa,x)]=1;
		if(fd(fa,y)==fd(fa,y+n))jh[fd(fa,y)]=1;
	}
	for(int i=1;i<=m;i++){
		int x=e[i].x,y=e[i].y;
		if(v[x]==1&&v[y]==1)
			tag1[fd(fa1,x)]=1;
		if(v[x]==-1&&v[y]==-1)
			tag2[fd(fa2,x)]=1;
	}
	for(int i=1;i<=q;i++){
		int x,y;rd(x,y);
		if(fd(fa,x)!=fd(fa,y)&&fd(fa,x)!=fd(fa,y+n))continue;
		if(v[x]!=1||v[y]!=-1)continue;
		if((!jh[fd(fa,x)])&&(fd(fa,x)==fd(fa,y)))continue;
		if(fd(fa3,x)==fd(fa3,y))ans[i]=1;
		else if(tag1[fd(fa1,x)]&&tag2[fd(fa2,y)])ans[i]=1;
	}
	for(int i=1;i<=q;i++)printf("%d",ans[i]);
	printf("\n");
	return 0;
}

标签:...,ch,题解,查集,R8,P10572,路径,rightarrow
From: https://www.cnblogs.com/11-twentythree/p/18240937

相关文章

  • LibreOJ #10131. 「一本通 4.4 例 2」暗的连锁 题解 树上差分
    暗的连锁题目描述Dark是一张无向图,图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N−1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。你的任务是把Dark斩为不连通的两部分。一开始Da......
  • [题解]P9433 [NAPC-#1] Stage5 - Conveyors
    P9433[NAPC-#1]Stage5-Conveyors题意简述给定一个\(N\)个节点的树形结构,每条边有边权,树上有\(k\)个关键点。接下来有\(q\)次询问,每次询问给定\(x,y\)两点,请计算从\(x\)开始经过这\(k\)个关键点(可以重复经过)再到\(y\)的最短路程。解题思路我们可以发现,如果\(x\)与\(y\)都......
  • 牛客周赛 Round 46 题解 C++
    目录 A 乐奈吃冰B 素世喝茶C 爱音开灯D 小灯做题E 立希喂猫F 祥子拆团 A 乐奈吃冰#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<set>#include<vector>#include<unordered_map>......
  • 斜率优化DP简单总结&&“土地购买”题解
    今天刚刷完了斜率优化DP,简单从头回顾一下。\[首先,能写出DP方程应该是最重要的,毕竟斜率只是用来优化的\]那么一个DP方程能用斜率优化,具备一种形式:\[f[i]+s1[i]+A[i]*B[j]=f[j]+s2[j]\]其中,f[i]表示所求值,(s1[i]、A[i])与(s2[j]、B[j])分别表示只与i或j有关的一个表达式(可以是只有常......
  • Codeforces Round 837题解(A、B)
    A.HossamandCombinatorics\(|a_i-a_j|\)最大的就是最大值和最小值,注意要开longlong。intn;inta[N];voidsolve(){cin>>n;intmin_v=INF,max_v=0;for(inti=1;i<=n;i++){cin>>a[i];min_v=min(min_v,a[i......
  • CF1970F1 Playing Quidditch (Easy) 题解
    一道大模拟题。这道题可以用一个 map 记录球员及鬼飞球当时的坐标,用一个数组 a 记录是否有人进球,用另一个数组 b 记录每位球员是否有鬼飞球。当球员抓住鬼飞球后,鬼飞球跟着这个球员移动,直到这个球员投球。话不多说,直接上代码。MyCode:#include<bits/stdc++.h>#de......
  • 【题解】 [CSP-J 2019] 纪念品
    题目描述题目大意在\(T\)天内,有\(n\)种纪念品和初始的\(m\)元。可以得到每天每种纪念品的价格。每一天可以以当日价格买卖纪念品。特别的,当天卖出得到的钱可以当天买入,当日买入的纪念品也可以当日卖出。当然可以一直持有。但是,\(T\)天过后,手上不可以持有纪念品。思路......
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 机场航班调度程序(100分) - 三语言A
    ......
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 最富裕的小家庭(100分) - 三语言AC
    ......
  • P7690 [CEOI2002] A decorative fence 题解
    cnblogs如果只是询问方案数,是P2467[SDOI2010]地精部落这道题,设\(f_{i,j,1/0}\)表示以\(j\)个数中从小到大的第\(i\)个数处于高/低位开头的方案数。显然有\[\begin{aligned}\begin{cases}f_{i,j,1}=\sum_{k=1}^{i-1}f_{k,j-1,0}\\f_{i,j,0}=\sum_{k=i}......