作业介绍

后缀数组

#include <bits/stdc++.h>
using namespace std;
const int N = 2e6+5;
int n,rk[N],sa[N];
string s;
int sum[N],x[N],y[N],m=255;
void GetSA(){
	//1.按照第一个字符基数排序
	for(int i=1;i<=n;i++)sum[x[i]=s[i]]++;
	for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
	for(int i=n;i>=1;i--)sa[sum[x[i]]--]=i;
	
	
	for(int k=1;k<=n;k<<=1){
		int num = 0;
		for(int i=n-k+1;i<=n;i++)y[++num] = i;
		for(int i=1;i<=n;i++)if(sa[i]>k)y[++num] = sa[i]-k;
		
		for(int i=1;i<=m;i++)sum[i] = 0;
		for(int i=1;i<=n;i++)sum[x[i]]++;
		for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
		for(int i=n;i>=1;i--)sa[sum[x[y[i]]]--] = y[i],y[i] = 0;
		
		swap(x,y);
		x[sa[1]] = 1;
		num = 1;
		
		for(int i=2;i<=n;i++){
			x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
		}
		if(num==n)break;
		m=num;
	}
}
int main(){
	cin>>s;
	n = s.size();
	s = "#"+s;
	GetSA();
	for(int i=1;i<=n;i++){
		cout<<sa[i]<<" ";
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6+5;
int n,rk[N],sa[N],k,old[N];
string s;
bool cmp(int x,int y){
	if(rk[x]!=rk[y])return rk[x]<rk[y];
	else return rk[x+k]<rk[y+k];
}
int main(){
	cin>>s;
	n = s.size();
	s="#"+s;
	for(int i=1;i<=n;i++){
		rk[i] = s[i];
		sa[i] = i;
	}
	for(k=1;k<n;k<<=1){
		sort(sa+1,sa+n+1,cmp);
		memcpy(old,rk,sizeof(rk));
		int num = 0;
		for(int i=1;i<=n;i++){
			if(old[sa[i]]==old[sa[i-1]] && old[sa[i]+k]==old[sa[i-1]+k])rk[sa[i]]=num;
			else rk[sa[i]] = ++num;
		}
	}
	for(int i=1;i<=n;i++){
		cout<<sa[i]<<" ";
	}
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6+5;
int x[N],y[N],rk[N],sa[N],height[N],sum[N];
string s;
int n,m=256;
void GetSA(){
	for(int i=1;i<=n;i++)sum[x[i]=s[i]]++;
	for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
	for(int i=n;i>=1;i--)sa[sum[x[i]]--]=i;
	
	for(int k=1;k<=n;k<<=1){
		int num = 0;
		for(int i=n-k+1;i<=n;i++)y[++num] = i;
		for(int i=1;i<=n;i++)if(sa[i]>k)y[++num] = sa[i]-k;
		for(int i=1;i<=m;i++)sum[i]=0;
		for(int i=1;i<=n;i++)sum[x[i]]++;
		for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
		for(int i=n;i>=1;i--)sa[sum[x[y[i]]]--]=y[i],y[i]=0;
		swap(x,y);
		num = 1;
		x[sa[1]] = 1;
		for(int i=2;i<=n;i++){
			x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
		}
		if(num==n)break;
		m = num;
	}
}
void GetHeight(){
	for(int i=1;i<=n;i++)rk[sa[i]] = i;
	int k = 0;
	for(int i=1;i<=n;i++){
		if(rk[i]==1)continue;
		if(k)k--;
		while(s[i+k]==s[sa[rk[i]-1]+k])k++;
		height[rk[i]] = k;
	}
}
int main(){
	cin>>s;
	n =s.size();
	s = "#"+s;
	GetSA();
	GetHeight();
	for(int i=1;i<=n;i++){
		cout<<sa[i]-1<<" ";
	}
	cout<<endl;
	for(int i=1;i<=n;i++){
		cout<<height[i]<<" ";
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
#define int long long
int n,a[N],b[N],id[N];
string s;
int sa[N],rk[N],height[N];
int st[N][21];
int x[N],y[N],sum[N],m;
void GetSA(){
	for(int i=1;i<=n;i++)sum[x[i]=id[i]]++;
	for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
	for(int i=n;i>=1;i--)sa[sum[x[i]]--]=i;
	
	for(int k=1;k<=n;k<<=1){
		int num = 0;
		for(int i=n-k+1;i<=n;i++)y[++num] = i;
		for(int i=1;i<=n;i++)if(sa[i]>k)y[++num]=sa[i]-k;
		for(int i=1;i<=m;i++)sum[i] = 0;
		for(int i=1;i<=n;i++)sum[x[i]]++;
		for(int i=1;i<=m;i++)sum[i]+=sum[i-1];
		for(int i=n;i>=1;i--)sa[sum[x[y[i]]]--]=y[i],y[i]=0;
		swap(x,y);
		
		num = 1;
		x[sa[1]] = 1;
		for(int i=2;i<=n;i++){
			x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
		}
		if(num==n)break;
		m = num;
	}
}
void GetHeight(){
	for(int i=1;i<=n;i++)rk[sa[i]] = i;
	int k = 0;
	for(int i=1;i<=n;i++){
		if(rk[i]==1)continue;
		if(k)k--;
		while(id[i+k]==id[sa[rk[i]-1]+k])k++;
		height[rk[i]] = k;
	}
}
void GetST(){
	for(int i=1;i<=n;i++){
		st[i][0] = height[i];
	}
	for(int j=1;j<=20;j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			st[i][j] = min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
}
int GetMin(int x,int y){
	int t = log2(y-x+1);
	return min(st[x][t],st[y-(1<<t)+1][t]);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i] = a[i];
	}
	reverse(a+1,a+n+1);
	sort(b+1,b+n+1);
	int tot = unique(b+1,b+n+1)-b-1;
	m = tot;
	for(int i=1;i<=n;i++){
		id[i] = lower_bound(b+1,b+tot+1,a[i])-b;
	}
	GetSA();
	GetHeight();
	GetST();
	set<int>s;
	int res = 0;
	for(int i=n;i>=1;i--){
		s.insert(rk[i]);
		auto it = s.find(rk[i]);
		int k = 0;
		if(it!=s.begin()){
			auto p = *(--it);
			k = GetMin(p+1,rk[i]);
			++it;
		}
		++it;
		if(it!=s.end()){
			auto p = *it;
			k = max(k,GetMin(rk[i]+1,p));
		}
		res+=n-i+1-k;
		cout<<res<<endl;
	}
	return 0;
}
状态
已结束
题目
11
开始时间
2026-5-16 0:00
截止时间
2026-5-23 23:59
可延期
24 小时