[CF1685C]Bring Balance

做题时间:2022.8.11

\(【题目描述】\)

给定一个长为 \(2n(1\leq \sum n\leq 2\times 10^5)\) 的括号序列 \(s\) ,包含 \(n\) 个左括号和 \(n\) 个右括号,现在可以反转 \(s\) 的一些字串,问最少反转多少次可以将 \(s\) 变成合法字串,并输出构造方案。

\(【输入格式】\)

多组数据,第一行一个整数 \(T\) 表示数据组数

每组数据第一行一个 \(n\)

第二行一个长为 \(2n\) 的括号序列 \(s\)

\(【输出格式】\)

对于每组数据,第一行一个整数表示最少操作次数 \(k\)

接下来 \(k\) 行每行两个整数 \(l_i,r_i\) 表示反转的区间

\(【考点】\)

数形结合

\(【做法】\)

分析括号序列、01序列等可以考虑数形结合,即将左括号(1)看成+1,右括号(0)看成-1,建立一个折线图再分析。

对于这道题,经过观察发现,反转一个区间 \([l,r]\) 相当于将其中的点以线段 \(lr\) 的中点进行中心对称,而目标即为将所有低于x轴的点(下称为关键点)全部翻上x轴,但这也会使得原先高于x轴的点翻下x轴。而 \([l,r]\) 中高度最高的肯定最容易被翻下x轴,根据几何证明可以发现,假设 \(a\) 为最高点,若 \(h_a\leq h_l+h_r\) 则反转 \([l,r]\) 时不会将任何一个点翻下x轴,因此可以考虑找可以将所有关键点包括在其中并符合上述条件的 \([l,r]\) ,然后直接反转 \([l,r]\) 即可;若找不到,记 \(\max\) 为高度最高的点,则反转 \([l,\max]\)\([\max,n\times 2]\) 即可。

详细题解

#include<cstdio>
#include<iomanip>
#define INF 0x7f7f7f7f
using namespace std;
const int N=2e5+50;
char s[N];
int h[N],pm,pk[N],ed1,ed2;
//pm记录最高点,pk记录所有低于x轴的点 
int n,t;
inline int Max(int a,int b){return a>b?a:b;}


pair<int,int> Work(int l,int r)//计算[l,r]的最大值 
{
	int maxn=-INF,pos=0;
	for(int i=l;i<=r;i++){
		if(h[i]>maxn){
			maxn=h[i],pos=i;
		}
	}
	return make_pair(maxn,pos);
}
bool Check()
{
	int ml=0,mr=0,mm=0;
	pair<int,int> l,r,mid; 
	
	
	//注意这里h[i]表示i的前缀和,因此0才表示第一个括号,下面输出左区间+1也是同理 
	l=Work(0,pk[1]);
	mid=Work(pk[1],pk[ed2]);
	r=Work(pk[ed2],n*2);
	
	if(l.first+r.first>=mid.first){//有[l,r]满足条件 
		printf("1\n");
		printf("%d %d\n",l.second+1,r.second);
		return true;
	}
	return false;
}
void Print()
{
	if(!ed2){//原序列为合法序列,不需要反转 
		printf("0\n");
		return ;
	}
	if(!Check()){//若没有[l,r]满足条件 
		printf("2\n");
		printf("1 %d\n%d %d\n",pm,pm+1,2*n);
	}
}
void Pre()//初始化点的高度 
{
	ed1=ed2=0;
	for(int i=1;i<=n*2;i++){
		if(s[i]=='(') h[i]=h[i-1]+1;
		else h[i]=h[i-1]-1;
	}
}

void Solve()
{
	scanf("%d",&n);
	scanf("%s",s+1);
	Pre();
	int maxn=-INF;//注意有的点可能<0,因此maxn不能设为0,上同 
	for(int i=1;i<=n*2;i++){
		if(h[i]>=maxn){
			pm=i;
			maxn=h[i];
		}
		if(h[i]<0) pk[++ed2]=i;
	}
}
int main()
{
	scanf("%d",&t);
	while(t--){
		Solve();
		Print();
	}
	return 0;
}
posted @ 2022-08-11 19:27  lxzy  阅读(74)  评论(0)    收藏  举报