QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#596#389784#7742. Suffix StructureFlamireFlamireSuccess!2024-04-14 19:51:032024-04-14 19:51:03

详细

Extra Test:

Time Limit Exceeded

input:

100001
100000 100000
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 9...

output:

5000149999 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...

result:


ID题目提交者结果用时内存语言文件大小提交时间测评时间
#389784#7742. Suffix StructureFlamireTL 334ms130208kbC++174.4kb2024-04-14 19:44:032024-04-14 19:54:38

answer

#include <bits/stdc++.h>
#define N 200011
#define pii pair<int,int>
#define s1 first
#define s2 second
#define M N*32
#define ll long long
#define ull unsigned long long
using namespace std;
map<int,int> ch[N];int T,n,m,fail[N],t[N];
int lc[M],rc[M],val[M],sz,rt[N];
void modi(int k,int p,int L,int R,int x,int &c)
{
	if(!c)c=++sz,lc[c]=lc[x],rc[c]=rc[x];//printf("modi(%d,%d,[%d,%d],%d,%d)\n",k,p,L,R,x,c);
	if(L==R){val[c]=p;return;}
	if(k<=L+R>>1)
	{
		if(lc[x]==lc[c])lc[c]=0;
		modi(k,p,L,L+R>>1,lc[x],lc[c]);
	}
	else
	{
		if(rc[x]==rc[c])rc[c]=0;
		modi(k,p,(L+R>>1)+1,R,rc[x],rc[c]);
	}
}
int query(int k,int L,int R,int x)
{//printf("query(%d,[%d,%d],%d)\n",k,L,R,x);
	if(!x)return 0;
	if(L==R)return val[x];
	if(k<=L+R>>1)return query(k,L,L+R>>1,lc[x]);return query(k,(L+R>>1)+1,R,rc[x]);
}
void build()
{
	queue<int> q;fail[0]=0;for(auto x:ch[0])fail[x.s2]=0,q.push(x.s2),modi(x.s1,x.s2,1,n,0,rt[0]);
	while(!q.empty())
	{
		int p=q.front();q.pop();//printf("p:%d\n",p);
		if(!ch[p].empty())for(auto x:ch[p])modi(x.s1,x.s2,1,n,rt[fail[p]],rt[p]);
		else rt[p]=rt[fail[p]];
		for(auto x:ch[p])
		{//printf("found edge %d->%d %d\n",p,x.s2,x.s1);
			fail[x.s2]=query(x.s1,1,n,rt[fail[p]]);
			q.push(x.s2);
		}
	}
}
ll ans[N],ansd[N],h[N],f[N];
int fa[N][21],dep[N],len[N],to[N];
const int B=801801801;
int anc(int u,int k){for(int i=20;~i;--i)if(k>=1<<i)u=fa[u][i],k-=1<<i;return u;}
unordered_map<ull,int> stH;
void dfs(int u,int F,ull H)
{
	fa[u][0]=F;for(int i=1;i<=20;++i)fa[u][i]=fa[fa[u][i-1]][i-1];
	stH[H]=u;
	for(auto v:ch[u])if(v.s2^F)dep[v.s2]=dep[u]+1,dfs(v.s2,u,H*B+v.s1);
}
ull pw[N],tH[N];
void dfslen(int u,int F,ull H)
{//printf("dfslen(%d,%d,%llu)\n",u,F,H);
	int L=0,R=m;
	while(L<=R)
	{
		int md=L+R>>1;//printf("md:%d hsh:%llu\n",md,H*pw[md]+tH[md]);
		if(stH.find(H*pw[md]+tH[md])!=stH.end())len[u]=md,L=md+1;else R=md-1;
	}
	to[u]=fail[stH[H*pw[len[u]]+tH[len[u]]]];
	for(auto v:ch[u])if(v.s2^F)dfslen(v.s2,u,H*B+v.s1);
}
int id[N];
bool cmp(int a,int b){return dep[a]<dep[b];}
int p[N],c[N];
int main()
{
	pw[0]=1;for(int i=1;i<N;++i)pw[i]=pw[i-1]*B;
	scanf("%d",&T);while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;++i)scanf("%d",p+i);
		for(int i=1;i<=n;++i)scanf("%d",c+i);
		for(int i=1;i<=m;++i)scanf("%d",t+i);
		for(int i=0;i<=n;++i)ch[i].clear(),rt[i]=0;sz=0;
		for(int i=1;i<=n;++i)ch[p[i]][c[i]]=i;
		build();stH.clear();
		// printf("fail:");for(int i=1;i<=n;++i)printf("%d ",fail[i]);putchar(10);
		dep[0]=0;dfs(0,0,0);
		for(int i=1;i<=n;++i)id[i]=i;
		sort(id+1,id+1+n,cmp);
		for(int i=1;i<=m;++i)tH[i]=tH[i-1]*B+t[i];
		// printf("tH:");for(int i=1;i<=m;++i)printf("%llu ",tH[i]);putchar(10);
		dfslen(0,0,0);
		// printf("len:");for(int i=0;i<=n;++i)printf("%d ",len[i]);putchar(10);
		// printf("to:");for(int i=0;i<=n;++i)printf("%d ",to[i]);putchar(10);
		for(int i=1;i<=m;++i)ans[i]=ansd[i]=h[i]=0;
		f[0]=0;for(int i=1;i<=n;++i)f[i]=1;
		for(int i=n;i;--i)
		{
			int u=id[i];//printf("=======================================================u:%d f:%d to:%d\n",u,f[u],to[u]);
			if(len[u]==m)
			{
				ansd[1]+=f[u];ansd[m+1]-=f[u];
				ans[1]+=dep[u]*f[u];ans[m+1]-=dep[u]*f[u];
			}
			else
			{
				if(dep[to[u]]>len[u])
				{
					int v=anc(to[u],len[u]);//printf("u:%d v:%d dep:%d\n",u,v,dep[v]);
					ans[1]+=(dep[u]-dep[v])*f[u];
					ans[len[u]+1]-=(dep[u]-dep[v])*f[u];//printf("ans[%d,%d]+=%d*%d\n",1,len[u],(dep[u]-dep[v]),f[u]);
					f[v]+=f[u];
				}
				else
				{
					ansd[1]+=f[u];ansd[len[u]+1]-=f[u];h[len[u]]+=f[u];ans[1]+=dep[u]*f[u];ans[len[u]+1]-=dep[u]*f[u];//printf("ansd[%d,%d]+=%d,ans[%d,%d]+=%d*%d\n",1,len[u],f[u],1,len[u],dep[u],f[u]);
					// printf("-h[%d]\n",len[u]);
					f[0]+=f[u];//printf("f0<-%lld\n",f[u]);
				}
			}
		}
		for(int i=m-1;i;--i)h[i]+=h[i+1];
		// printf("h:");for(int i=1;i<=m;++i)printf("%lld ",h[i]);putchar(10);
		// printf("f:");for(int i=0;i<=n;++i)printf("%lld ",f[i]);putchar(10);
		// printf("f0:%lld\n",f[0]);
		for(int i=1;i<=m;++i)ans[i]+=ans[i-1];
		for(int i=1;i<=m;++i)
		{
			ansd[i]+=ansd[i-1];
			ans[i]+=ansd[i]*i;
		}//printf("pre ans:");for(int i=1;i<=m;++i)printf("%lld ",ans[i]);putchar(10);
		int c=0;
		for(int i=1;i<=m;++i)
		{
			c=query(t[i],1,n,rt[c]);//printf("i:%d c:%d coe:%lld\n",i,c,f[0]-h[i]);
			ans[i]-=h[i]*dep[c];ans[i]+=f[0]*dep[c];
		}
		for(int i=1;i<=m;++i)printf("%lld ",ans[i]);putchar(10);
	}
	fclose(stdin);fclose(stdout);return 0;
}