Luogu8235 solution

Problem

link->https://www.luogu.com.cn/problem/P8235

Solution

容易发现,长度为 \(n\) 的括号序列使得包含合法括号序列做多的最佳情况是:

\[\begin{matrix}\underbrace{\texttt{()()()()......()()}}\\\lfloor\frac{n}{2}\rfloor\texttt{ 个()}\end{matrix}+n\bmod2\texttt{ 个(} \]

那么,我们将问题转换到树上,那么最佳情况无疑是对于树上的每条链都可以形成如上所述的结构。

我们可以以 \(1\) 为根节点,对整棵树进行遍历,假定 \(s_u\) 代表点 \(u\) 的括号类型(\(s_u=0\) 代表点 \(u\) 为左括号,反之亦然),那么对于每一个 \(u\) 的子节点 \(v\),则 \(s_v=s_u \oplus 1\),则可以构成最佳情况下的括号树(即每条链都为上述序列的结构)。

Code

#include<bits/stdc++.h>
#define pd push_back
#define pb pop_back
#define mk make_pair
//#define int long long
#define PII pair<int,int>
#define _for(a,b,c) for(int a=b;a<=c;a++)
#define _rep(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
template <typename T> inline void read(T& x) {
	x=0; T f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch&15); ch=getchar(); }
	x=x*f;
	return;
}
template <typename T,typename ...Arg> inline void read(T& x,Arg& ...arg){
	read(x); read(arg...);
}
int power(int a,int b) {
	int ans=1;
	do {
		if(b&1) ans*=a; a*=a;
	} while(b>>=1);
	return ans;
}
const int N=1e6+5;
int f[N],head[N],n,tot;
char s[N];
struct node {
	int to,nxt;
}; node Edge[N<<1];
void Add_Edge(int u,int v) {
	++tot; Edge[tot]=node{v,head[u]}; head[u]=tot;
}
void Dfs(int u,int fa,bool tag) {
	s[u]=(tag? '(':')');
	for(int i=head[u];i;i=Edge[i].nxt)
		if(Edge[i].to!=fa)
			Dfs(Edge[i].to,u,tag^1);
}
signed main() {
	read(n);
	_for(i,1,n-1) {
		int u,v; read(u,v); Add_Edge(u,v); Add_Edge(v,u);
	}
	Dfs(1,0,1);
	_for(i,1,n)
		putchar(s[i]);
	return 0;
}

posted @ 2022-08-01 14:15  lsj2009  阅读(47)  评论(0)    收藏  举报