QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#275343#2840. 绿绿与串串luyiming123TL 3ms14504kbC++142.0kb2023-12-04 17:03:122023-12-04 17:03:12

Judging History

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

  • [2023-12-04 17:03:12]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:14504kb
  • [2023-12-04 17:03:12]
  • 提交

answer

# include <bits/stdc++.h>
using namespace std;
using i64 = int;
const i64 base = 131;
const int N = 1e6 + 5; 
char S[N];
int n, len; 
int ok[N]; 
array<i64, 2> Hash[N][2], mod{(i64)(1e9 + 7), 998244353}, pbase[N]; 
array<i64, 2> Get(int l, int r, int flag)
{
	// if(flag == 1) swap(l, r);
	if(l > r) return {0, 0};
	array <i64, 2> ans{0, 0}; 
	if(flag == 0)
	{
		for(int i = 0; i <= 1; i++)
			ans[i] = (Hash[r][flag][i] - (1ll * Hash[l - 1][flag][i] * pbase[r - l + 1][i] % mod[i]) + mod[i]) % mod[i];	
	}
	else
	{
		for(int i = 0; i <= 1; i++)
			ans[i] = (Hash[l][flag][i] - (1ll * Hash[r + 1][flag][i] * pbase[r - l + 1][i] % mod[i]) + mod[i]) % mod[i];
	}
	return ans;
}
int check(int x)
{	
	// printf("check : %d\n", x);
	if(ok[x] != -1) return ok[x]; 
	int l = 1, r = min(n - x + 1, x), ans = 0;
	while(l <= r) 
	{
		int mid = (l + r) >> 1; 
		if(Get(x - mid + 1, x - 1, 0) == Get(x + 1, x + mid - 1, 1)) {ans = mid; l = mid + 1; }
		else r = mid - 1;
	}
	// printf("ans = %d\n", ans);
	if(ans == min(n - x + 1, x)) 
	{
		if(ans == x) return (ok[x] = check(x + ans - 1)); 
		else return (ok[x] = 1); 
	}
	else return (ok[x] = 0);
}
int main(void)
{	
	// freopen("2.in", "r", stdin); freopen("out.out", "w", stdout);
	int Test; scanf("%d", &Test);
	pbase[0] = {1ll, 1ll}; 
	for(int i = 1; i <= N - 5; i++) 
		for(int j = 0; j <= 1; j++)
			pbase[i][j] = 1ll * pbase[i - 1][j] * base % mod[j]; 
	while(Test--)
	{
		scanf("%s", S + 1); n = strlen(S + 1); 
		for(int i = 1; i <= n; i++) 
		{
			ok[i] = -1;
			for(int j = 0; j <= 1; j++) Hash[i][0][j] = ((1ll * Hash[i - 1][0][j] * base % mod[j]) + (S[i] - 'a')) % mod[j]; 
		}
		Hash[n + 1][0] = Hash[n + 1][1] = {0, 0};
		for(int i = n; i >= 1; i--)
		{
			ok[i] = -1;
			for(int j = 0; j <= 1; j++) Hash[i][1][j] = ((1ll * Hash[i + 1][1][j] * base % mod[j]) + (S[i] - 'a')) % mod[j]; 
		}
		ok[1] = (n == 1) ? 1 : 0; 
		for(int i = 1; i <= n; i++)
		{
			if(check(i)) printf("%d ", i); 
		}
		printf("\n");
	}
	return 0; 
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 14504kb

input:

7
abcdcb
qwqwq
qaqaqqq
carnation
c
ab
aa

output:

4 6 
2 3 4 5 
6 7 
9 
1 
2 
2 

result:

ok 7 lines

Test #2:

score: -100
Time Limit Exceeded

input:

5
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc...

output:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 10...

result: