QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#511239#6963. Border Queriesship2077AC ✓339ms30532kbC++143.0kb2024-08-09 17:55:222024-08-09 17:55:23

Judging History

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

  • [2024-08-09 17:55:23]
  • 评测
  • 测评结果:AC
  • 用时:339ms
  • 内存:30532kb
  • [2024-08-09 17:55:22]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
constexpr int M=2e6+5;
int n,m,q,len,N,nxt[M],w[M],R[M];
string S,T,str; long long sum1[M],sum2[M];
int cnt[M],rnk[M],sa[M],id[M],oldrnk[M],height[M];
void SA(int n){ int m=255;
    for (int i=1;i<=m;i++) cnt[i]=0;
    for (int i=1;i<=n;i++) cnt[rnk[i]=str[i]]++;
    for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
    for (int i=n;i;i--) sa[cnt[rnk[i]]--]=i;
    for (int lim=1;lim<=n;lim<<=1){ int num=0;
        for (int i=n-lim+1;i<=n;i++) id[++num]=i;
        for (int i=1;i<=n;i++) if (sa[i]>lim) id[++num]=sa[i]-lim;
        for (int i=1;i<=m;i++) cnt[i]=0; int idx=0;
        for (int i=1;i<=n;i++) cnt[rnk[id[i]]]++;
        for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
        for (int i=n;i;i--) sa[cnt[rnk[id[i]]]--]=id[i];
        for (int i=1;i<=n;i++) oldrnk[i]=rnk[i];
        #define cmp(x,y) x+lim<=n&&y+lim<=n&&oldrnk[x]==oldrnk[y]&&oldrnk[x+lim]==oldrnk[y+lim]
        for (int i=1;i<=n;i++) rnk[sa[i]]=cmp(sa[i-1],sa[i])?idx:++idx;
        if ((m=idx)==n) break;
    }
    for (int i=1,k=0;i<=n;i++){ if (k) k--;
        while (i+k<=n&&sa[rnk[i]-1]+k<=n&&str[i+k]==str[sa[rnk[i]-1]+k]) k++;
        height[rnk[i]]=k;
    }
}
void solve(){
    cin>>n>>m>>q>>S>>T;
    str=S;str.erase(str.begin());
    str.pop_back();str+="@"+T;
    len=str.length();N=n-1;
    str=" "+str; S=" "+S; T=" "+T;
    SA(len);
    for (int i=2,j=0;i<=n;i++){
        while (j&&S[j+1]!=S[i]) j=nxt[j];
        nxt[i]=j+=S[j+1]==S[i];
    }
    // cerr<<str<<" !"<<endl;
    // for (int i=1;i<=len;i++) cerr<<sa[i]<<", ";cerr<<endl;
    // for (int i=1;i<=len;i++) cerr<<height[i]<<", ";cerr<<endl;
    // for (int i=1;i<=n;i++) cerr<<nxt[i]<<", ";cerr<<endl;
    for (int i=1;i<=n;i++) w[i]=0;
    for (int i=nxt[n];i;i=nxt[i]) w[n-i]++; w[n]=w[n-1]=0;
    // for (int i=1;i<=n;i++) cerr<<w[i]<<", ";cerr<<endl;
    for (int i=1;i<=n;i++) w[i]+=w[i-1];
    for (int i=1;i<=m;i++) R[i]=0;
    for (int i=1,tmp=0;i<=len;i++)
        if (sa[i]<N) tmp=INT_MAX;
        else R[sa[i]-N]=tmp=min(tmp,height[i]);
    // for (int i=1;i<=m;i++) cerr<<R[i]<<",, ";cerr<<endl;
    for (int i=len,tmp=0;i;i--)
        if (sa[i]<N) tmp=height[i];
        else R[sa[i]-N]=max(R[sa[i]-N],tmp),tmp=min(tmp,height[i]);
    // for (int i=1;i<=m;i++) cerr<<R[i]<<",, ";cerr<<endl;
    for (int i=1;i<=m;i++) sum1[i]=sum1[i-1]+w[R[i]];
    for (int i=1;i<=m;i++) sum2[i]=sum2[i-1]+w[i];
    while (q--){ long long ans=0;
        int ql,qr;cin>>ql>>qr;
        int l=ql,r=qr,p=qr+1;
        while (l<=r){
            int mid=l+r>>1;
            if (R[mid]>qr-mid+1) p=mid,r=mid-1;
            else l=mid+1;
        }
        if (ql<p) ans+=sum1[p-1]-sum1[ql-1];
        // for (int i=ql;i<p;i++) ans+=w[R[i]];
        if (p<=qr) ans+=sum2[qr-p+1];
        // for (int i=p;i<=qr;i++) ans+=w[qr-i+1];
        printf("%lld\n",ans);

    }
}
int main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int T;cin>>T;while (T--) solve(); return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 339ms
memory: 30532kb

input:

505
100000 100000 100000
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww...

output:

3579782
6647236
543408
1673575
456027
1296061
252861
4897583
1410669
1339129
3294734
2698709
2851056
5252310
99237
3201517
3090024
971847
4390041
1287976
195415
4077820
1123243
4935851
6733092
1928419
1575734
86265
1752391
1584396
4164128
864018
2810862
3600267
5599859
1105190
336828
2609252
4712144...

result:

ok 1000000 lines