求助
查看原帖
求助
308464
奇米楼主2020/6/17 10:39
#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
#define int long long 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

const int mod=1e9+7;
const int mo=998244353;
const int N=3e5+5;
const int inf=1e18;

int n,m,SA[N],x[N],y[N],ton[N],siz[N],mi[N],Ans[N];
int ans1[N],ans2[N],mx[N],val[N],a[N],High[N],fa[N],id[N];
char ch[N];

inline void getSA()
{
	For(i,1,n) ton[(x[i]=a[i])]++;
	For(i,1,m) ton[i]+=ton[i-1];
	Dow(i,n,1) SA[ton[x[i]]--]=i;
	for ( int k=1;k<=n;k<<=1 )
	{
		int cnt=0;
		For(i,n-k+1,n) y[++cnt]=i;
		For(i,1,n) if(SA[i]>k) y[++cnt]=SA[i]-k;
		For(i,1,m) ton[i]=0;
		For(i,1,n) ton[x[i]]++;
		For(i,1,m) ton[i]+=ton[i-1];
		Dow(i,n,1) SA[ton[x[y[i]]]--]=y[i],y[i]=0;
		swap(x,y);
		cnt=1;
		SA[x[1]]=1;
		For(i,2,n) x[SA[i]]=(y[SA[i]]==y[SA[i-1]]&&y[SA[i]+k]==y[SA[i-1]+k])?cnt:++cnt;
		if(cnt==n) break;
		m=cnt;
	}
}

inline void getHigh()
{
	int k=0;
	For(i,1,n)
	{
		int j=SA[x[i]-1];
		if(k) k--;
		while(a[i+k]==a[j+k]) k++;
		High[x[i]]=k;
	}
}

inline int find(int x)
{
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

inline void merge(int x,int y,int len)
{
	x=find(x),y=find(y);
	fa[x]=y;
	ans2[len]+=1ll*siz[x]*siz[y];
	siz[y]+=siz[x];
	Ans[y]=max(Ans[y],Ans[x]);
	Ans[y]=max(Ans[y],max(mi[x]*mi[y],mx[x]*mx[y]));
	ans1[len]=max(ans1[len],Ans[y]);
	mi[y]=min(mi[y],mi[x]);
	mx[y]=max(mx[y],mx[x]);
}

signed main()
{
	n=read();
	scanf("%s",ch+1);
	For(i,1,n) a[i]=(ch[i]-'a'+1);
	For(i,1,n) val[i]=read(),id[i]=i;
	m=26;
	getSA();
	getHigh();	
	For(i,1,n)
	{
		fa[i]=i,siz[i]=1;
		mi[i]=mx[i]=val[i];
		ans1[i]=-inf;
		Ans[i]=-inf;
	}
	For(i,1,n-1) merge(x[SA[i]],x[SA[i+1]],High[SA[i+1]]);
	Dow(i,n-1,1) ans1[i]=max(ans1[i],ans1[i+1]);
	Dow(i,n-1,1) ans2[i]+=ans2[i+1];
	For(i,1,n)
	{
		printf("%lld ",ans2[i]);
		if(!ans2[i]) puts("0"); else printf("%lld\n",ans1[i]);
	}
	return 0;
}
/*
10
ponoiiipoi
2 1 4 7 4 8 3 6 4 7
*/

2020/6/17 10:39
加载中...