QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#646302 | #7748. Karshilov's Matching Problem II | Yeyin_0 | TL | 0ms | 16600kb | C++23 | 3.0kb | 2024-10-16 22:07:20 | 2024-10-16 22:07:28 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fe(i,a,b) for(int i=(a);i>=(b);i--)
const int N=150010;
const LL mod=1e9+7;
const LL MOD[5]={0,131,13331,1141,1145143};
LL ksm[5][N];
int n,m;
string s,t;
LL w[N],reach[N],sumw[N];
LL Ans=0,ans[N],kmp[N],val[N];
int bn;
struct pii
{
LL first;
LL second;
LL num;
};
struct Hash
{
LL hash[5];
} sums[N],sumt[N];
vector<pii> q;
Hash cut(Hash i,Hash j,LL num)
{
Hash k;
fo(o,1,4)
k.hash[o]=(j.hash[o]-i.hash[o]*ksm[o][num]%mod+mod)%mod;
return k;
}
bool equal(Hash i,Hash j)
{
fo(k,1,4)
if(i.hash[k]!=j.hash[k])
return 0;
return 1;
}
bool cmp(pii i,pii j)
{
if((i.first-1)/bn==(j.first-1)/bn)
{
return i.second<j.second;
}
return (i.first-1)/bn<(j.first-1)/bn;
}
bool check(LL start,LL len)
{
return equal(cut(sumt[start-1],sumt[start+len-1],len),cut(sums[0],sums[len],len));
}
void work()
{
fo(j,1,n) kmp[j]=j-1;
kmp[1]=0;
fo(j,2,n)
{
int cnt=kmp[j-1];
while(s[cnt+1]!=s[j]&&cnt!=0)
{
cnt=kmp[cnt];
}
if(s[cnt+1]==s[j]) kmp[j]=cnt+1;
else kmp[j]=0;
}
val[0]=0;
fo(j,0,n)
{
if(kmp[j]==0) val[j]=w[j];
else val[j]=val[kmp[j]]+w[j];
}
int cnt=0;
for(int i=0;i*bn<n;i++)
{
int l=i*bn+1;
int r=l-1;
int u=0;
Ans=0;
while(cnt<m&&(q[cnt].first-1)/bn==i)
{
while(r<q[cnt].second)
{
++r;
while(s[u+1]!=t[r]&&u!=l-1) u=kmp[u];
if(s[u+1]==t[r]) Ans+=val[u+1],u++;
}
LL count=0;
fo(j,l,q[cnt].first-1)
{
count+=sumw[min(reach[j],q[cnt].second-j+1)];
}
ans[q[cnt].num]=Ans-count;
cnt++;
}
}
}
int main()
{
fo(i,1,4) ksm[i][0]=1;
fo(i,1,N-5)
{
fo(o,1,4)
ksm[o][i]=ksm[o][i-1]*MOD[o]%mod;
}
cin>>n>>m;
bn=min(n,(int)sqrt(n)+1);
cin>>s;
cin>>t;
s=" "+s;
t=" "+t;
fo(i,1,n) cin>>w[i];
fo(i,1,n)
{
sumw[i]=sumw[i-1]+w[i];
fo(o,1,4)
{
sums[i].hash[o]=(sums[i-1].hash[o]*MOD[o]+s[i]-'a'+1)%mod;
sumt[i].hash[o]=(sumt[i-1].hash[o]*MOD[o]+t[i]-'a'+1)%mod;
}
}
fo(i,1,n)
{
LL l=1,r=n-i+1;
while(l<=r)
{
LL mid=(l+r)>>1;
if(check(i,mid)) l=mid+1;
else r=mid-1;
}
reach[i]=l-1;
}
fo(i,1,m)
{
int l,r;
cin>>l>>r;
q.push_back({l,r,i});
//cout<<"s:"<<cut(sums[l-1],sums[r],r-l+1).hash[1]<<endl;
//cout<<"t:"<<cut(sumt[l-1],sumt[r],r-l+1).hash[1]<<endl;
}
sort(q.begin(),q.end(),cmp);
work();
fo(i,1,m)
{
cout<<ans[i]<<endl;
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 16600kb
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: 0ms
memory: 15920kb
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...