90分MLE求调
查看原帖
90分MLE求调
660641
0zhouyq楼主2023/3/14 22:10

第五个点 MLEMLE 了。

TrieTrie 建字典树。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
string str[100100];
int s2[100100];
int cnt,siize[510010];
int s[510100][26],ans[100100],vis[510100];
int insert(string x,int yy){
	int len=x.length(),now=0,ret=yy;
	for(int i=1;i<=len;i++){
		if(s[now][x[i-1]-'a']==0) s[now][x[i-1]-'a']=++cnt;
		now=s[now][x[i-1]-'a'];
		ret=min(ret,yy-vis[now]);
	}
	vis[now]=yy;
	return ret;
}
void insert2(string x,int yy){
	int len=x.length(),now=0;
	for(int i=1;i<=len;i++){
		if(s[now][x[i-1]-'a']==0) s[now][x[i-1]-'a']=++cnt;
		now=s[now][x[i-1]-'a'];
	}
	vis[now]=yy;
}
void dfs(int p){
	siize[p]=(vis[p]>0);
	for(int i=0;i<26;i++) if(s[p][i]!=0){
		dfs(s[p][i]);
		siize[p]+=siize[s[p][i]];
	}
}
struct node{
	int x,num;
};
bool cmp(node aa,node bb){
	if(aa.num==0) return false;
	if(aa.num!=bb.num) return aa.num<bb.num;
	return aa.x<bb.x;
}
int did(int p,int *f){
	int f2[100001];
	int cntt=0,cnttt=0;
	for(int i=0;i<26;i++){
		if(s[p][i]==0) continue;
		if(vis[s[p][i]]) f[++cntt]=s[p][i];
		else cnttt+=did(s[p][i],&f2[cnttt]);
	}
	for(int i=cntt+1;i<=cntt+cnttt;i++){
		f[i]=f2[i-cntt];
	}
	return cntt+cnttt;
}
int cnt2=0;
void init(int p){
	if(vis[p]) s2[++cnt2]=vis[p];
	int nuum=26;
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > gt;
	for(int i=0;i<26;i++){
		if(s[p][i]==0){
			nuum--;
			continue;
		}
		if(vis[s[p][i]]==0){
			nuum--;
			int f[100001];
			int len=did(s[p][i],&f[0]);
			for(int i=1;i<=len;i++){
				gt.push(make_pair(siize[f[i]],f[i]));
				nuum++;
			}
		} 
		else{
			gt.push(make_pair(siize[s[p][i]],s[p][i]));
		}
	}
	while(!gt.empty()){
		init(gt.top().second);
		gt.pop();
	}
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>str[i];
		int len=str[i].length();
		for(int j=1;j*2<=len;j++) swap(str[i][j-1],str[i][len-j]);
	}
	for(int i=1;i<=n;i++){
		insert2(str[i],i);
	}
	dfs(0);
	init(0);
	for(int i=0;i<=510099;i++){
		for(int j=0;j<26;j++) s[i][j]=0;
		vis[i]=0;
	}
	cnt=0;
	for(int i=1;i<=n;i++){
		ans[i]=insert(str[s2[i]],i);
	}
	ll rans=0;
	for(int i=1;i<=n;i++) rans+=ans[i];
	cout<<rans;
	return 0;
}
2023/3/14 22:10
加载中...