QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#282344#7748. Karshilov's Matching Problem IIgrass8cow#TL 1ms3920kbC++171.8kb2023-12-11 20:11:132023-12-11 20:11:14

Judging History

你现在查看的是最新测评结果

  • [2024-08-25 20:42:18]
  • hack成功,自动添加数据
  • (/hack/789)
  • [2023-12-11 20:11:14]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3920kb
  • [2023-12-11 20:11:13]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
int n,m,kmp[150100],is[150100],f[150100][20];
int z[150100],q[151000];
char s[150100],t[150100];
#define ll long long
ll w[151000],ds[150010];
int T[150100],cn,ls[10100000],rs[10100000];
ll su[10100000];
void up(int &p,int lst,int l,int r,int x,int z){
	p=++cn,su[p]=su[lst]+z,ls[p]=ls[lst],rs[p]=rs[lst];
	if(l==r)return;int mid=(l+r)>>1;
	if(x<=mid)up(ls[p],ls[lst],l,mid,x,z);
	else up(rs[p],rs[lst],mid+1,r,x,z);
}
ll ask(int p,int l,int r,int x){
	if(l==r)return su[p];
	int mid=(l+r)>>1;
	if(x<=mid)return ask(ls[p],l,mid,x);
	return su[ls[p]]+ask(rs[p],mid+1,r,x);
}
void Z(){
	z[1]=n;
	for(int i=2,j=0,mr=0;i<=n;i++){
		if(i<=mr)z[i]=min(mr-i+1,z[i-j+1]);
		while(i+z[i]<=n&&s[1+z[i]]==s[i+z[i]])z[i]++; 
		if(i+z[i]-1>mr)j=i,mr=i+z[i]-1;
	}
	for(int i=1,j=0,mr=0;i<=n;i++){
		if(i<=mr)q[i]=min(mr-i+1,z[i-j+1]);
		while(i+q[i]<=n&&s[1+q[i]]==t[i+q[i]])q[i]++;
		if(i+q[i]-1>mr)j=i,mr=i+q[i]-1;
	}
}
void K(){
	for(int i=2,j=0;i<=n;i++){
		while(j&&s[j+1]!=s[i])j=kmp[j];
		if(s[j+1]==s[i])j++;kmp[i]=j,f[i][0]=j;
	}
	for(int j=1;j<20;j++)for(int i=1;i<=n;i++){
		if(!f[i][j-1])f[i][j]=0;
		else f[i][j]=f[f[i][j-1]][j-1];
	}
	for(int i=1,j=0;i<=n;i++){
		while(j&&s[j+1]!=t[i])j=kmp[j];
		if(s[j+1]==t[i])j++;is[i]=j;
	}
}
int main(){
	scanf("%d%d%s%s",&n,&m,s+1,t+1);
	for(int i=1;i<=n;i++)scanf("%lld",&w[i]),w[i]+=w[i-1];
	Z(),K();
	for(int i=1;i<=n;i++)ds[i]=ds[kmp[i]]+w[i];
	for(int i=n;i;i--){
		T[i]=T[i+1];
		if(q[i]&&i+q[i]<=n)up(T[i],T[i],1,n,i+q[i],w[q[i]]);
	}
	for(int i=1,l,r;i<=m;i++){
		scanf("%d%d",&l,&r);
		ll an=0;
		//an=ask(T[l],1,n,r);
		for(int j=l;j<=r;j++)if(j+q[j]-1<r)an+=w[q[j]];
		int u=is[r];
		if(u>r-l+1){
			for(int j=19;j>=0;j--)
			if(f[u][j]>r-l+1)u=f[u][j];
			u=kmp[u];
		}
		an+=ds[u];
		printf("%lld\n",an);
	}
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3764kb

input:

8 5
abbabaab
aababbab
1 2 4 8 16 32 64 128
1 1
2 3
3 5
4 7
1 8

output:

1
3
3
16
38

result:

ok 5 lines

Test #2:

score: 0
Accepted
time: 1ms
memory: 3920kb

input:

15 4
heheheheehhejie
heheheheheheheh
3 1 4 1 5 9 2 6 5 3 5 8 9 7 9
2 3
4 8
2 6
1 15

output:

3
13
13
174

result:

ok 4 lines

Test #3:

score: -100
Time Limit Exceeded

input:

150000 150000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:

108147037823514
221878585246974
455339807727642
440286198422821
148115747906237
88695249853257
351159618462315
58850354020997
65824434822005
270158033672354
197732558443069
298193894693053
239511187032650
28139154231325
408380171835227
268053430937402
32417121185965
104813548228675
44074926058619
78...

result: