QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#303196 | #7901. Basic Substring Structure | ucup-team134# | WA | 15ms | 13092kb | C++14 | 3.5kb | 2024-01-11 20:59:09 | 2024-01-11 20:59:10 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int N=200050;
int a[N];
int b[N];
ll Brute(int x,int n){
ll ans=0;
for(int newChar=1;newChar<=n;newChar++){
if(newChar==a[x])continue;
for(int i=1;i<=n;i++)b[i]=a[i];
b[x]=newChar;
ll now=0;
for(int i=1;i<=n;i++){
int j=0;
while(i+j<=n && b[1+j]==b[i+j])j++;
now+=j;
}
ans=max(ans,now);
}
return ans;
}
int sa[N],id[N],lcp[N];
array<int,3> tmp[N];
void BuildSA(int n){
for(int i=1;i<=n;i++)id[i]=a[i];
for(int j=1;;j<<=1){
for(int i=1;i<=n;i++){
tmp[i]={id[i],i+j<=n?id[i+j]:n+1,i};
}
sort(tmp+1,tmp+1+n);
int c=0;
for(int i=1;i<=n;i++){
id[tmp[i][2]]=c+1;
if(i==n || !(tmp[i][0]==tmp[i+1][0] && tmp[i][1]==tmp[i+1][1]))c++;
}
if(c==n)break;
}
for(int i=1;i<=n;i++)sa[id[i]]=i;
}
void BuildLCP(int n){
int k=0;
for(int i=1;i<=n;i++){
if(id[i]!=n){
int other=sa[id[i]+1];
while(max(other,i)+k<=n && a[other+k]==a[i+k])k++;
lcp[id[i]]=k;
}
if(k>0)k--;
}
}
const int L=20;
int rmq[N][L],logs[N];
void BuildST(int n){
for(int i=2;i<=n;i++)logs[i]=logs[i>>1]+1;
for(int i=1;i<=n;i++)rmq[i][0]=lcp[i];
for(int j=1;j<L;j++){
for(int i=1;i<=n-(1<<j)+1;i++){
rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
}
}
}
int LCP(int a,int b,int n){
int l=id[a];
int r=id[b];
if(l>r)swap(l,r);
if(l==r)return n-l+1;
int k=logs[r-l];
return min(rmq[l][k],rmq[r-(1<<k)][k]);
}
int R[N],len[N];
vector<int> endsHere[N],loHere[N];
int main(){
int t;
scanf("%i",&t);
while(t--){
int n;
scanf("%i",&n);
for(int i=1;i<=n;i++)scanf("%i",&a[i]);
a[n+1]=n+1;
BuildSA(n+1);
BuildLCP(n+1);
BuildST(n+1);
ll sumL=0;
int cntR=0;
ll sumR=0;
for(int i=2;i<=n;i++){
len[i]=LCP(1,i,n);
R[i]=i+len[i];
if(R[i]<=n){
sumL+=len[i];
endsHere[R[i]].pb(i);
}else{
cntR++;
sumR+=i;
}
loHere[min(len[i]+1,i)].pb(i);
}
ll sumLo=0;
int cntHi=0;
ll sol=0;
for(int i=n;i>=1;i--){
ll ans=sumL;
//printf("sumL %lld\n",sumL);
ans+=(ll)cntR*i-sumR;
//printf("sumR %lld (%i)\n",(ll)cntR*i-sumR,cntR);
ans+=n;
ans+=sumLo;
//printf("sumLo %lld\n",sumLo);
ans+=cntHi*(i-1);
//printf("sumHi %lld (%i)\n",cntHi*(i-1),cntHi);
map<int,ll> best;
for(int j:endsHere[i]){
int newChar=a[len[j]+1];
int lcp=len[j]+1+min(LCP(j+len[j]+1,len[j]+2,n),i-1-len[j]-1);
if(lcp==i-1){
if(newChar==a[j+lcp]){
lcp++;
lcp+=LCP(len[j]+2,j+lcp,n);
}
}
//printf("[E]: Change to %i -> %i new lcp %lld\n",newChar,j,lcp);
best[newChar]+=lcp-len[j];
}
for(int j:loHere[i]){
if(len[j]==i-1 && j+i<=n){
int newChar=a[j+i-1];
int lcp=len[j]+1+LCP(i+1,j+i,n);
//printf("[L]: Change to %i -> %i new lcp %lld\n",newChar,j,lcp);
best[newChar]+=lcp-len[j];
}
}
if(best.size()){
ll mx=best.begin()->second;
for(auto p:best){
//printf("Add %lld for char %i\n",p.second,p.first);
mx=max(mx,p.second);
}
ans+=mx;
}
//printf("i=%i ans=%lld brute=%lld\n",i,ans,Brute(i,n));
sol+=ans^i;
for(int j:endsHere[i]){
sumL-=len[j];
sumR+=j;
}
cntR+=endsHere[i].size();
sumR-=i;
cntR--;
sumLo+=len[i];
for(int j:loHere[i]){
sumLo-=len[j];
cntHi++;
}
}
printf("%lld\n",sol);
for(int i=1;i<=n;i++){
endsHere[i].clear();
loHere[i].clear();
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 13092kb
input:
2 4 2 1 1 2 12 1 1 4 5 1 4 1 9 1 9 8 10
output:
15 217
result:
ok 2 lines
Test #2:
score: -100
Wrong Answer
time: 15ms
memory: 13084kb
input:
10000 8 2 1 2 1 1 1 2 2 9 2 2 1 2 1 2 1 2 1 15 2 1 2 1 1 1 1 2 2 1 2 1 2 2 1 2 1 1 10 2 1 1 1 2 2 1 1 2 2 3 2 1 2 11 1 2 2 1 1 2 1 2 2 1 1 14 2 1 1 1 1 2 1 1 1 2 2 1 2 1 12 2 2 2 1 2 2 2 1 1 2 1 2 4 2 1 1 2 8 1 2 2 2 1 2 1 1 8 1 1 2 1 2 1 1 1 6 2 1 1 1 2 2 14 2 2 1 1 1 1 2 2 2 1 2 2 1 1 10 1 2 2 1 1...
output:
100 132 350 3 210 9 263 360 279 15 95 110 61 353 224 4 338 351 373 310 3 14 118 66 15 89 34 254 8 64 28 94 91 103 253 194 23 50 311 63 96 17 21 65 314 361 268 306 353 284 332 281 230 319 4 332 57 329 4 60 32 148 321 45 353 91 246 3 158 352 246 17 154 3 404 396 390 75 267 363 17 57 23 280 4 17 352 39...
result:
wrong answer 1st lines differ - expected: '94', found: '100'