1. 程式人生 > 實用技巧 >有道

有道

如果一個括號序列插入"+"和"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);
}