用SA A了,但是不理解
查看原帖
用SA A了,但是不理解
656765
STARSczy楼主2024/4/25 16:42
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),i##end=(r);i<=i##end;++i)
#define per(i,r,l) for(int i=(r),i##end=(l);i>=i##end;--i)
#define int long long
#define double long double
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
const int maxn=1e6+10,maxm=1e6+10,mod=1e9+7;
inline int read(){
	int c,w=0,n=0;
	while((c=getchar())<'0'||'9'<c) w=c=='-';
	do n=n*10+c-'0';while('0'<=(c=getchar())&&c<='9');
	return w?-n:n;
}
int write(int n){
	if(n<0) putchar('-'),n=-n;
	if(n>9) write(n/10);
	putchar(n%10+'0');
	return n;
}
inline int ksm(int x,int k,int mod=mod){
	int ans=1;
	for(;k;k>>=1,x=x*x%mod) if(k&1) ans=ans*x%mod;
	return ans;
}

int n,t[maxn],a[maxn],b[maxn],rkb[maxn],sa[maxn],rk[maxn];
int h,ans,height[maxn],st[maxn][21],nxt[maxn],lst[maxn];
string s;

signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>s,n=s.size(),s=(char)0+s,height[0]=height[n+1]=-1;
	rep(i,1,n) t[s[i]]=1;
	rep(i,1,128) t[i]+=t[i-1];
	rep(i,1,n) rk[i]=t[s[i]-1]+1;
	for(int l=1;l<=n;l<<=1){
		rep(i,1,n) a[i]=rk[i],b[i]=i+l<=n?rk[i+l]:0;
		rep(i,0,n) t[i]=rkb[i]=0;
		rep(i,1,n) ++t[b[i]+1];
		rep(i,1,n) t[i]+=t[i-1];
		rep(i,1,n) rkb[++t[b[i]]]=i;
		rep(i,0,n) t[i]=0;
		rep(i,1,n) ++t[a[i]+1];
		rep(i,1,n) t[i]+=t[i-1];
		rep(i,1,n) sa[++t[a[rkb[i]]]]=rkb[i];
		rep(i,1,n) if(a[sa[i-1]]==a[sa[i]]&&b[sa[i-1]]==b[sa[i]]) rk[sa[i]]=rk[sa[i-1]];
		else rk[sa[i]]=i;
	}
	rep(i,1,n) if(rk[i]>1){
		for(int j=sa[rk[i]-1];max(i,j)+h<=n&&s[i+h]==s[j+h];++h);
		st[rk[i]-1][0]=height[rk[i]-1]=h,h=max(0ll,h-1);
	}
	per(i,n,1) for(nxt[i]=i+1;height[i]<height[nxt[i]];nxt[i]=nxt[nxt[i]]);
	rep(i,1,n) for(lst[i]=i-1;height[i]<=height[lst[i]];lst[i]=lst[lst[i]]);
	rep(i,1,n) ans+=2*(i-lst[i])*(nxt[i]-i)*height[i];
	cout<<n*(n-1)*(n+1)/2-ans;
	return 0;
}

其中,这两行代码


	per(i,n,1) for(nxt[i]=i+1;height[i]<height[nxt[i]];nxt[i]=nxt[nxt[i]]);
	rep(i,1,n) for(lst[i]=i-1;height[i]<=height[lst[i]];lst[i]=lst[lst[i]]);

改成


	per(i,n,1) for(nxt[i]=i+1;height[i]<=height[nxt[i]];nxt[i]=nxt[nxt[i]]);
	rep(i,1,n) for(lst[i]=i-1;height[i]<=height[lst[i]];lst[i]=lst[lst[i]]);

或


	per(i,n,1) for(nxt[i]=i+1;height[i]<height[nxt[i]];nxt[i]=nxt[nxt[i]]);
	rep(i,1,n) for(lst[i]=i-1;height[i]<height[lst[i]];lst[i]=lst[lst[i]]);

都不对,为什么改成最一边大于,一边小于那种就对了?

2024/4/25 16:42
加载中...