最长合法括号序列
如果一个括号序列插入"+"和"1"后,可以得到一个正确的数学表达式,那么它被称为"合法"的。例如,序列"(())()","()"和"(()(()))"是合法的,但")(","(()"和"(()))("不是合法的。 给出一个由"("和")"字符组成的字符串。你要找出它最长的是合法括号序列的子串,也同样要找出最长子串的个数。100%的数据:读入的字符串长度小于
等于10^6
样例输入 Copy
)()()(
样例输出 Copy
4 1
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
const int N=1000005;
int n,tot;
int f[N],Q[N];
char s[N];
void init()
{int i;
scanf("%s",s+1);//下标从1开始
n=strlen(s+1);
}
void dp()
{int i,k;
tot=0;//记录栈中元素个数
for (i=1;i<=n;i++)
if (s[i]=='(')//是左小括号
Q[++tot]=i;
else
if (tot>0)
{k=Q[tot];
//该")"与位置k的"("匹配
tot--;
f[i]=f[k-1]+i-k+1;
//f[i]表示到位置i能够形成的最长合法括号序列的子串的长度
}
}
void out()
{int i,ans=0, cnt=0;
for (i=1;i<=n;i++)
{if (f[i]==ans)
cnt++;
if (f[i]>ans)
{ans=f[i];
cnt=1;
}
}
if (ans==0) cnt=1;
printf("%d %d\n",ans,cnt);
}
int main()
{
init();
dp();
out();
return 0;
}
Noip2019括号树
https://blog.csdn.net/xuxiayang/article/details/103739252?utm_medium=distribute.pc_relevant.none-task-blog-title-3&spm=1001.2101.3001.4242
#include<bits/stdc++.h>
#include<cctype>
#include<algorithm>
#define LL long long
#define N 500010
using namespace std;int n,l[N],tot,stk[N],top,fa[N];
struct node{int next,to;}e[N];
char s[N];
inline void add(int u,int v)
{
e[++tot]=(node){l[u],v};
l[u]=tot;
return;
}
LL sum[N],f[N],res;
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void dfs(int x)
{
int tmp=0;
if(s[x]==')')
{
if(top)
{
tmp=stk[top];
f[x]=f[fa[stk[top]]]+1;
top--;
}
}
else
stk[++top]=x;
sum[x]=sum[fa[x]]+f[x];
for(register int i=l[x];i;i=e[i].next)
dfs(e[i].to);
if(tmp)
stk[++top]=tmp;
else
if(top)
top--;
return;
}
signed main()
{
n=read();
scanf("%s",s+1);
for(register int i=2;i<=n;i++)
fa[i]=read(),add(fa[i],i);
dfs(1);
for(register int i=1;i<=n;i++)
{
// cout<<i<<" "<<sum[i]<<endl;
res^=1ll*i*sum[i];
}
printf("%lld",res);
}

浙公网安备 33010602011771号