记录编号 372143 评测结果 AAAAAAAAAA
题目名称 [SDOI 2016 Round1] 生成魔咒 最终得分 100
用户昵称 Gravatar甘罗 是否通过 通过
代码语言 C++ 运行时间 0.689 s
提交时间 2017-02-17 19:27:56 内存使用 24.73 MiB
显示代码纯文本
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>
#include<cmath>
#define N 200010
using namespace std;

int i,len;
set <int> v;
int c[N],C[N],a[N],f[N][20],fh[N],fq[N];
int sa[N],rank[N],height[N],wa[N],wb[N],wv[N],ss[N];

inline int Min(int a,int b){return (a<b)?a:b;}
inline int cmp(int *r,int x,int y,int l){return (r[x]==r[y]&&r[x+l]==r[y+l]);}

inline int read(){
	int p=0;	char c=getchar();
	while (c<'0'||c>'9')	c=getchar();
	while (c>='0'&&c<='9')	p=p*10+c-48,c=getchar();
	return p;
}

inline int Query(int x,int y){
	int p=(int)(log(y-x+1)/log(2));
	return Min(f[x][p],f[y+1-(1<<p)][p]);
}

inline int Pred(int x){
	set <int>::const_iterator y=v.lower_bound(x);
	if (y!=v.begin())	return *--y;
	else return 0;
}

inline int Succ(int x){
	set <int>::const_iterator y=v.lower_bound(x);
	if (y!=v.end())	return *y;
	else return 0;
}

inline void SA(int *r,int *sa,int n,int m){
	int i,j,p,*t,*x=wa,*y=wb;
	for (i=0;i<m;i++)	ss[i]=0;
	for (i=0;i<n;i++)	ss[x[i]=r[i]]++;
	for (i=1;i<m;i++)	ss[i]+=ss[i-1];
	for (i=n-1;i>=0;i--)	sa[--ss[x[i]]]=i;
	for (j=p=1;p<n;j<<=1,m=p){
		for (p=0,i=n-j;i<n;i++)	y[p++]=i;
		for (i=0;i<n;i++)	if (sa[i]>=j)	y[p++]=sa[i]-j;
		for (i=0;i<n;i++)	wv[i]=x[y[i]];
		for (i=0;i<m;i++)	ss[i]=0;
		for (i=0;i<n;i++)	ss[wv[i]]++;
		for (i=1;i<m;i++)	ss[i]+=ss[i-1];
		for (i=n-1;i>=0;i--)	sa[--ss[wv[i]]]=y[i];
		for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
		x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
	}
}

inline void HA(int *r,int *sa,int n){
	int i,j,k=0;
	for (i=1;i<=n;i++)	rank[sa[i]]=i;
	for (i=0;i<n;height[rank[i++]]=k)
	for (k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}

inline void Ready(){
	int i=0,j=0;
	for (i=1;i<=len;i++)	f[i][0]=height[i];
	for (j=1;(1<<j)<len;j++)
		for (i=1;i<=len-j;i++)
			f[i][j]=Min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
	for (i=1;i<len;i++)	fh[i]=i+1;
	for (i=2;i<=len;i++)	fq[i]=i-1;
}

inline void Work(){
	int i=0,j=0,x=0,y=0,cnt=0;
	for (i=len-1;i>=0;i--){
		j=rank[i];	x=Pred(j);	y=Succ(j);
		if (x!=0&&y!=0)	cnt-=Query(x+1,y);
		if (x!=0)	cnt+=Query(x+1,j);
		if (y!=0)	cnt+=Query(j+1,y);
		v.insert(j);
		printf("%lld\n",(long long)(len-i)*(len-i+1)/2-(long long)cnt);
	}
}

int main(){
	freopen("menci_incantation.in","r",stdin);
	freopen("menci_incantation.out","w",stdout);
	len=read();
	for (i=0;i<len;i++)	c[i]=read(),a[i]=c[i];
	sort(a,a+len);
	int *end=unique(a,a+len);
	for (i=0;i<len;i++)	C[len-1-i]=lower_bound(a,end,c[i])-a+1;
	C[len]=0;
	SA(C,sa,len+1,len+1);	HA(C,sa,len);
	Ready();	Work();
	return 0;
}