QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#511254 | #6963. Border Queries | ship2077 | AC ✓ | 296ms | 34256kb | C++14 | 2.6kb | 2024-08-09 18:04:50 | 2024-08-09 18:04:50 |
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],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