日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF653F. Paper task

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF653F. Paper task 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CF653F. Paper task

簡要題面

給定括號序列SSS,求其中本質不同合法括號序列個數。(∣S∣≤5?105|S|\leq 5*10^5S5?105)

Solution

感覺用了一個很麻煩的方法。
我們可以考慮枚舉本質不同串的右端點,每次動態地在SAMSAMSAM里面加入末尾元素,新增的本質不同后綴個數rrr即為lenlst?lenfa[lst]len_{lst}-len_{fa[lst]}lenlst??lenfa[lst]?,顯然新增的本質不同串的起點是[1,r][1,r][1,r],終點是iii

現在我們考慮有多少起點在[1,r][1,r][1,r]中的序列合法,我們對于1..i1..i1..i做一個括號匹配,倘若有左括號沒被消掉,則起點只可能在沒消掉的左括號右邊,令l=max(stk[i])l=max(stk[i])l=max(stk[i]),表示最右邊的未消掉的左括號。

此時起點在[l+1,r][l+1,r][l+1,r]的串顯然只需要滿足一個條件——左右括號個數相等即可(因為此時左括號個數不可能多于右括號),因此建一個線段樹維護區間內左右括號個數差即可。

Code

#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-15; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int mods=1e9+7; const int MAXN=500005; const int INF=0x3f3f3f3f;//1061109567 /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } char st[MAXN]; int n,s[MAXN],stk[MAXN],top=0; PR S[MAXN<<2]; void build(int x,int l,int r) {if (l==r) { S[x]=MP(s[l],1); return; }int mid=(l+r)>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);S[x].fi=min(S[x<<1].fi,S[x<<1|1].fi),S[x].se=0;if (S[x].fi==S[x<<1].fi) S[x].se+=S[x<<1].se;if (S[x].fi==S[x<<1|1].fi) S[x].se+=S[x<<1|1].se; } PR query(int x,int l,int r,int L,int R) {if (l>=L&&r<=R) return S[x];int mid=(l+r)>>1;if (R<=mid) return query(x<<1,l,mid,L,R);else if (L>mid) return query(x<<1|1,mid+1,r,L,R);else{PR X=query(x<<1,l,mid,L,mid),Y=query(x<<1|1,mid+1,r,mid+1,R);if (X.fi==Y.fi) return MP(X.fi,X.se+Y.se);return (X.fi<Y.fi)?X:Y;} } int len[MAXN<<1],t[MAXN<<1][2],fa[MAXN<<1],sz=2,lst=1; void insert(int c) {int p=lst,np=lst=sz++;len[np]=len[p]+1;for (;p&&!t[p][c];p=fa[p]) t[p][c]=np;if (!p) { fa[np]=1; return; }int q=t[p][c];if (len[q]==len[p]+1) fa[np]=q;else{int nq=sz++;len[nq]=len[p]+1;fa[nq]=fa[q];fa[np]=fa[q]=nq;memcpy(t[nq],t[q],sizeof t[0]);for (;t[p][c]==q;p=fa[p]) t[p][c]=nq;} } signed main() {n=read();scanf("%s",st+1);for (int i=1;i<=n;i++) s[i]=s[i-1]+(st[i]=='('?1:-1);build(1,0,n-1);ll ans=0;for (int i=1;i<=n;i++){if (st[i]=='(') stk[++top]=i;else if (top) stk[top--]=0;int l=stk[top]+1;insert(st[i]==')');int r=len[lst]-len[fa[lst]];if (l<=r){PR t=query(1,0,n-1,l-1,r-1);if (t.fi==s[i]) ans+=t.se;}}printf("%lld\n",ans);return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的CF653F. Paper task的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。