代码求卡常
  • 板块灌水区
  • 楼主xyz123
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/8/26 09:39
  • 上次更新2024/8/26 11:49:42
查看原帖
代码求卡常
379926
xyz123楼主2024/8/26 09:39
O(nlogn longn)的算法,数据5e5
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+10;
unsigned int tree[N][26],idx;
unsigned int cnt[N];
unsigned long long pw1[N],h1[N];
char s[N];
inline void insert(){
	unsigned int n=strlen(s+1);
	unsigned int cur=0;
	cnt[cur]=1;
	for(unsigned int i=1;i<=n;i++){
		unsigned int v=s[i]-'a';
		if(!tree[cur][v])	tree[cur][v]=++idx;
		cur=tree[cur][v];
		cnt[cur]=1;
	}
}
inline void dfs(unsigned int u){
	for(unsigned int i=0;i<26;i++){
		if(tree[u][i]){
			dfs(tree[u][i]);
			cnt[u]+=cnt[tree[u][i]];
		}
	}
}
unsigned long long mp[N];unsigned int tot;
unsigned int mp2[N];
pair<unsigned long long,unsigned int>ddd[N];
void dfs2(unsigned int u,unsigned long long h1){
	ddd[tot++]={h1,cnt[u]};
	for(unsigned int i=0;i<26;i++){
		if(tree[u][i]){
			dfs2(tree[u][i],h1*31+i+1);
		}
	}
}
unsigned int n,m;
inline unsigned int find2(unsigned int l,unsigned int r,unsigned long long v){
	while(l<=r){
		int mid=(l+r)>>1;
		if(mp[mid]>v)	r=mid-1;
		else{
			if(mp[mid]==v)	return mid;
			else	l=mid+1;
		}
	}
	return 2147483647;
}
int main(){
	scanf("%d%d",&n,&m);
	for(unsigned int i=1;i<=n;i++){
		scanf("%s",s+1);
		insert();
	}
	dfs(0);
	dfs2(0,0);
	stable_sort(ddd,ddd+tot);
	for(unsigned int i=0;i<tot;i++){
		mp[i]=ddd[i].first;
		mp2[i]=ddd[i].second;
	}
	scanf("%s",s+1);
	pw1[0]=1;
	for(unsigned int i=1;i<=m;i++)	pw1[i]=pw1[i-1]*31;
	for(unsigned int i=1;i<=m;i++)	h1[i]=h1[i-1]*31+s[i]-'a'+1;
	for(unsigned int i=1;i<=m;i++){
		if(find2(0,tot-1,s[i]-'a'+1)==2147483647){
			printf("0 %d\n",cnt[0]);
			continue;
		}
		unsigned int l=i,r=m;unsigned int mid;
		while(l<r){
			mid=(l+r+1)>>1;
			unsigned long long u=h1[mid]-h1[i-1]*pw1[mid-i+1];
			unsigned long long c=2147483647;//find2(0,tot-1,u);
			unsigned int l1=0,r1=tot-1;int mid1;
			while(l1<=r1){
				mid1=(l1+r1)>>1;
				if(mp[mid1]>u)	r1=mid1-1;
				else{
					if(mp[mid1]==u){
						c=mid1;
						break;
					}
					else	l1=mid1+1;
				}
			}
			if((c^2147483647)&&mp[c]==u)	l=mid;
			else	r=mid-1;
		}
		unsigned long long u=h1[l]-h1[i-1]*pw1[l-i+1];
		unsigned int c=find2(0,tot-1,u);
		printf("%d %d\n",l-i+1,mp2[c]);
	}
	return 0;
}
2024/8/26 09:39
加载中...