首页 > 其他分享 >[ARC141C] Bracket and Permutation

[ARC141C] Bracket and Permutation

时间:2023-12-13 09:01:06浏览次数:32  
标签:ch ++ Permutation 括号 Bracket cntq sl ARC141C nq

考虑假设已知括号序列 \(s\),如何求出 \(p,q\)。

对于求 \(p\),考虑从 \(s_1\) 到 \(s_n\) 逐个往里放,如果能放就直接放,肯定不劣,否则就从后面抽最近的左括号放过来,然后继续放。不难证明不存在更优方案,对于 \(q\) 同理。

接下来我们发现,如果 \(p\) 中存在 \(p_i < p_{i-1}\),\(s_{p_{i-1}}\) 必然为左括号,\(s_{p_i}\) 必然为右括号,对于 \(q\) 也有类似的结论。实际如果 \(p,q\) 合法,已经足以求出括号序列 \(s\) 了。

证明考虑画出括号序列的折线图,那么 \(p\) 求出的就是低于水平线的所有部分(对于水平线下的部分,设右括号分别位于 \(r_1,r_2 \dots r_k\),左括号位于 \(l_1,l_2 \dots l_k\),那么 \(\forall i,r_i < l_i\),所以每个左括号都会被抽到前面)。同理由于 \(q\) 是对中心对称后的折线图进行这一过程,其求出的自然是高于水平线的所有部分,拼起来自然就是整体。

当然,由于我们只利用了一部分信息求出便求出了答案,所以其余一部分信息可能与答案冲突。对求出的答案重新贪心一遍,判断贪心出的序列是否和 \(p,q\) 相同即可。

精细实现可以做到 \(O(n)\)。

代码实现
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
inline ll read() {
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=4e5+5;
int n,p[N],q[N];
char s[N];
bool ck_sit() {
    int nwp=0,nwq=0;
	for(int i=1;i<=n;i++) {
		if(s[p[i]]=='(') nwp++;
		else nwp--;
		if(s[q[i]]=='(') nwq++;
		else nwq--;
		if(nwp<0||nwq<0) return 0;
	}
	if(nwp||nwq) return 0;
	return 1;
}
int np[N],nq[N];
bool ck_mnmx() {
	int cntp=0,cntq=0,nw=0;
	set <int> sl;
	for(int i=1;i<=n;i++) if(s[i]=='(') sl.insert(i);
	for(int i=1;i<=n;i++) {
		if(s[i]=='('&&sl.find(i)==sl.end()) continue;
		if(s[i]=='(') sl.erase(i),nw++,np[++cntp]=i;
		else if(nw) nw--,np[++cntp]=i;
		else np[++cntp]=(*sl.begin()),sl.erase(*sl.begin()),np[++cntp]=i;
	}
	for(int i=1;i<=n;i++) if(np[i]!=p[i]) return 0;
	nw=0;sl.clear();
	for(int i=n;i>=1;i--) if(s[i]=='(') sl.insert(-i);
	for(int i=n;i>=1;i--) {
		if(s[i]=='('&&sl.find(-i)==sl.end()) continue;
		if(s[i]=='(') sl.erase(-i),nw++,nq[++cntq]=i;
		else if(nw) nw--,nq[++cntq]=i;
		else nq[++cntq]=-(*sl.begin()),sl.erase(*sl.begin()),nq[++cntq]=i;
	}
	for(int i=1;i<=n;i++) if(nq[i]!=q[i]) return 0;
	return 1;
}
int main() {
    n=read()*2;
    for(int i=1;i<=n;i++) p[i]=read();for(int i=1;i<=n;i++) q[i]=read();
    for(int i=2;i<=n;i++) if(p[i]<p[i-1]) s[p[i]]=')',s[p[i-1]]='(';
	for(int i=2;i<=n;i++) if(q[i]>q[i-1]) s[q[i]]=')',s[q[i-1]]='(';
	for(int i=1;i<=n;i++) if(s[i]!='('&&s[i]!=')') return puts("-1"),0;
	if(!ck_sit()||!ck_mnmx()) return puts("-1"),0;
	for(int i=1;i<=n;i++) cout<<s[i];
	cout<<'\n';
	return 0;
}

标签:ch,++,Permutation,括号,Bracket,cntq,sl,ARC141C,nq
From: https://www.cnblogs.com/Hypercube07/p/17898259.html

相关文章

  • E. Permutation Sorting
    E.PermutationSortingYouaregivenapermutation$^\dagger$$a$ofsize$n$.Wecallanindex$i$goodif$a_i=i$issatisfied.Aftereachsecond,werotateallindicesthatarenotgoodtotherightbyoneposition.Formally,Let$s_1,s_2,\ldots,s_k$......
  • 解决:Expected 1 line break before closing bracket, but no line breaks found.eslin
    运行时报错以下 解决在eslintrc.jsrules下添加以下代码'vue/singleline-html-element-content-newline':'off','vue/multiline-html-element-content-newline':'off', ......
  • [Codeforces] CF1858C Yet Another Permutation Problem
    YetAnotherPermutationProblem-洛谷这题本来很简单,思路我也想到了,但是代码一直没写对,思路也一直换来换去(悲然而发现最开始的思路是对的题意Alex收到了一个名为"GCD排列"的游戏作为生日礼物。这个游戏的每一轮进行如下操作:首先,Alex选择一个整数序列\(a_1,a_2,…,a_......
  • DPT Permutation
    题意给定\(S\in['>','<']\)。表示排列\(P\)两点之间的大小关系。求排列\(P\)的方案数。Sol排列方案,考虑\(f_{i,j}\)表示第\(i\)位的数在排列中排名为\(j\)的方案数。当\(S_i='>'\),\(f_{i,j}=\sum_{k=1}^{j-1}f_{i-1,k}\)。当\(S......
  • CF1858C Yet Another Permutation Problem
    CF1858CYetAnotherPermutationProblemYetAnotherPermutationProblem-洛谷这题本来很简单,思路我也想到了,但是代码一直没写对,思路也一直换来换去(悲然而发现最开始的思路是对的题意Alex收到了一个名为"GCD排列"的游戏作为生日礼物。这个游戏的每一轮进行如下操作:......
  • 题解 P7972【[KSN2021] Self Permutation】
    怎么其他两篇题解都是\(O(n\logn)\)的,来发一个\(O(n)\)做法,当考前复习了。对原序列建出小根笛卡尔树,节点编号与原序列中的下标相同。记\(T_u\)表示以\(u\)为根的子树,\(lc(u),rc(u)\)分别表示\(u\)的左儿子和右儿子。设\(f_u\)表示删除若干\(T_u\)中的点(可以不删......
  • CF1542E2 Abnormal Permutation Pairs (hard version) 题解
    怎么会有这么离谱的题目啊。【模板】前缀和优化dp。思路考虑一个基本的东西。由于要求字典序的限制。我们可以枚举最长公共前缀计算。考虑如何求长度为\(i\)的排列有\(j\)个逆序对的数量。设\(dp_{i,j}\)。\[dp_{i,j}=\sum_{k=0}^{i-1}dp_{i-1,j-k}\]就是枚举新的......
  • [题解] CF1156E Special Segments of Permutation
    SpecialSegmentsofPermutation给你一个排列\(p\),求有多少个区间\([l,r]\)满足\(p_l+p_r=\max_{i\in[l,r]}p_i\)。\(n\le2\times10^5\)。按最大值分治,记当前的分治中心为\(mid\),分治区间为\([l,r]\)。然后需要计算跨分治中心的贡献。如果\(mid-l......
  • 软件测试|好用的pycharm插件推荐(三)——Rainbow Brackets
    简介我们平时写代码的时候,括号是让我们非常头疼的地方,特别是代码逻辑很多,层层嵌套的情况。一眼很难看出,代码是从哪个括号开始,到哪个反括号结束的。这个时候要是有一款工具能够让我们一眼就看出代码从哪个括号开始,到哪个反括号结束,无疑对我们会有很大帮助。PyCharmRainbowBra......
  • SP15637 GNYR04H - Mr Youngs Picture Permutations(线性 dp)
    题目求方案数,考虑dp——状态设计和边界——题目告诉了一个很显然的性质:每一排从左至右保证高度单调递减每一列从后往前保证高度单调递减那么可以发现,对于每一行,每一列,一定是按高度顺序插入,并且是连续插入,因为如果不连续,就无法保证单调递减的性质同时,它给出了另一个性......