cunzai_zsy0531

关注我

CF653F Paper task 题解

题面

统计一个后缀和数组 \(suf_i\),其中 )\(1\)(\(-1\),那么一个子串 \(s_{l,r}\) 是一个合法括号序列,当且仅当 \(\min_{l\leq k \leq r}suf_k\geq suf_{r+1}\),并且 \(suf_l=suf_{r+1}\)

我们对这个串建立 SAM 之后,每个点表示的是某个前缀的一段区间的后缀。限制出来之后,可以使用 ST 表配合 vector 来找出满足上述限制的位置统计答案。总复杂度 \(O(n\log n)\)

点击查看代码
const int N=5e5+13;
namespace ST{
const int logN=23;
#define log2 _log2
int log2[N],f[N][logN];
inline void _init(int n){for(int i=2;i<=n;++i)log2[i]=log2[i>>1]+1;}
inline void init(int n){
	_init(n);
	int k=log2[n]+1;
	for(int j=1;j<=k;++j)
		for(int i=1;i+(1<<j)-1<=n;++i) f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
inline int query(int l,int r){int k=log2[r-l+1];return min(f[l][k],f[r-(1<<k)+1][k]);}
#undef log2
}
std::vector<int> a[N<<1];
#define P(i) a[(i)+N]
int n,suf[N];
char s[N];
int nxt[N<<1],len[N<<1],ed[N<<1],ptot=1,lastpos=1,son[N<<1][2],zrzak[2];
inline int newpos(int nson[2],int nlen){return len[++ptot]=nlen,son[ptot][0]=nson[0],son[ptot][1]=nson[1],ptot;}
inline void insert(int c,int pos){
	int p=lastpos,u=newpos(zrzak,len[p]+1);ed[u]=pos;
	while(p&&!son[p][c]) son[p][c]=u,p=nxt[p];
	lastpos=u;
	if(!p) return nxt[u]=1,void();
	int d=son[p][c];
	if(len[d]==len[p]+1) nxt[u]=d;
	else{
		int v=newpos(son[d],len[p]+1);ed[v]=ed[d];
		nxt[v]=nxt[d],nxt[d]=nxt[u]=v;
		while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
	}
}
inline bool check(int k,int pos){return ST::query(k,pos-1)>=suf[pos];}
int main(){
	read(n);read(s+1);
	for(int i=1;i<=n;++i) insert(s[i]=='(',i);
	for(int i=n;i;--i) suf[i]=suf[i+1]+(s[i]=='('?-1:1),ST::f[i][0]=suf[i];
	for(int i=1;i<=n;++i) P(suf[i]).pb(i);
	ST::init(n);ll ans=0;
	for(int i=2;i<=ptot;++i){
		int pos=ed[i]+1;int L=ed[i]-len[i]+1,R=ed[i]-len[nxt[i]];
		int l=std::lower_bound(P(suf[pos]).begin(),P(suf[pos]).end(),L)-P(suf[pos]).begin(),r=std::upper_bound(P(suf[pos]).begin(),P(suf[pos]).end(),R)-P(suf[pos]).begin()-1;
		int tmp=r;
		if(l>r||!check(P(suf[pos])[r],pos)) continue;
		while(l<r){
			int mid=(l+r)>>1;
			if(check(P(suf[pos])[mid],pos)) r=mid;
			else l=mid+1;
		}
		ans+=tmp-l+1;
	}
	println(ans);
	return 0;
}
posted @ 2022-05-18 21:35  cunzai_zsy0531  阅读(82)  评论(0编辑  收藏  举报