QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#511254#6963. Border Queriesship2077AC ✓296ms34256kbC++142.6kb2024-08-09 18:04:502024-08-09 18:04:50

Judging History

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

  • [2024-08-09 18:04:50]
  • 评测
  • 测评结果:AC
  • 用时:296ms
  • 内存:34256kb
  • [2024-08-09 18:04:50]
  • 提交

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],pos[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];
    }
    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++) 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=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++)
        sum1[i]=sum1[i-1]+w[R[i]],
        sum2[i]=sum2[i-1]+w[i],
        R[i]+=i-2;
    for (int i=1;i<=m<<1;i++) pos[i]=INT_MAX;
    for (int i=1;i<=m;i++) pos[R[i]]=min(pos[R[i]],i);
    for (int i=m<<1;i;i--) pos[i-1]=min(pos[i-1],pos[i]);
    while (q--){ long long ans=0;
        int ql,qr,p;cin>>ql>>qr;
        if (pos[qr]==INT_MAX) p=qr+1;
        else p=max(ql,pos[qr]);
        if (ql<p) ans+=sum1[p-1]-sum1[ql-1];
        if (p<=qr) ans+=sum2[qr-p+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;
}

详细

Test #1:

score: 100
Accepted
time: 296ms
memory: 34256kb

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