QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#303196#7901. Basic Substring Structureucup-team134#WA 15ms13092kbC++143.5kb2024-01-11 20:59:092024-01-11 20:59:10

Judging History

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

  • [2024-01-11 20:59:10]
  • 评测
  • 测评结果:WA
  • 用时:15ms
  • 内存:13092kb
  • [2024-01-11 20:59:09]
  • 提交

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'