QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#646329#7748. Karshilov's Matching Problem IIYeyin_0TL 0ms16080kbC++233.1kb2024-10-16 22:15:532024-10-16 22:15:54

Judging History

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

  • [2024-10-16 22:15:54]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:16080kb
  • [2024-10-16 22:15:53]
  • 提交

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,3)
        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;
    int p=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;
    }
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 15792kb

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: 16080kb

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:


result: