有道
阿新 • • 發佈:2020-09-10
如果一個括號序列插入"+"和"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); }