QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#511239 | #6963. Border Queries | ship2077 | AC ✓ | 339ms | 30532kb | C++14 | 3.0kb | 2024-08-09 17:55:22 | 2024-08-09 17:55:23 |
Judging History
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