记录编号 361493 评测结果 AAAAAAAAAA
题目名称 papertask 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.691 s
提交时间 2017-01-04 11:25:21 内存使用 43.22 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1000010;
long long ans;
char s[N];
int n,S[N],size,match[N],fa[N];
vector<int> Q[N];
void makepair(){
	for (int i=1;i<=n;i++)
		S[++size]=0,s[i]-='(';
	for (int i=1;i<=n;i++)
	if (s[i]) match[i]=S[size--];
		else S[++size]=i;
	for (int i=n;i;i--)
	if (s[i]&&!fa[i]){
		int now=i;
		do{
			fa[now]=i;
			now=match[now]-1;
			Q[i].push_back(now+1);
		}while (now&&s[now]);
		Q[i].push_back(-1);
		int len=Q[i].size()-1;
		for (int j=len;j;j--)
		if (j>len-j) swap(Q[i][j],Q[i][len-j]);
		/*printf("%d:\n",i);
		for (int j=0;j<Q[i].size();j++) printf("%d ",Q[i][j]);
		puts("");*/
	}
}
int find(int i,int x){
	i=fa[i];
	if (Q[i].empty()) return 0;
	int l=0,r=Q[i].size()-1;
	while (l!=r){
		int mid=(l+r)>>1;
		if (Q[i][mid+1]<=x) l=mid+1;else r=mid;
	}
	return l;
}
int go[N][2],len[N],par[N],Right[N],last,top;
int New(int L){len[++top]=L;return top;}
void extend(int n){
	int w=s[n],p=last,np=New(len[p]+1);
	Right[np]=n;
	while (p&&!go[p][w]) go[p][w]=np,p=par[p];
	if (!p) par[np]=1;
	else{
		int q=go[p][w];
		if (len[q]==len[p]+1) par[np]=q;
		else{
			int nq=New(len[p]+1);
			Right[nq]=n;
			memcpy(go[nq],go[q],sizeof go[q]);
			par[nq]=par[q];
			par[np]=par[q]=nq;
			while (p&&go[p][w]==q) go[p][w]=nq,p=par[p];
		}
	}
	ans+=find(n,n-len[par[np]])-find(n,n-len[np]);
	last=np;
}
int main()
{
	freopen("papertask.in","r",stdin);
	freopen("papertask.out","w",stdout);
	scanf("%d%s",&n,s+1);
	makepair();
	last=New(0);
	for (int i=1;i<=n;i++) extend(i);
	printf("%lld\n",ans);
	return 0;
}