QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#430414#7008. Rikka with Nice Counting Striking BackUnrealityAC ✓4443ms120680kbC++146.4kb2024-06-03 19:54:572024-06-03 19:54:57

Judging History

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

  • [2024-06-03 19:54:57]
  • 评测
  • 测评结果:AC
  • 用时:4443ms
  • 内存:120680kb
  • [2024-06-03 19:54:57]
  • 提交

answer

// Level 37 - 崇高性(Sublimity)
#include <bits/stdc++.h>
using namespace std;
#define _rep(i_,a_,b_) for(int i_ = (a_); i_ <= (b_); ++i_)
#define mid ((L+R) >> 1)
#define multiCase() int testCnt = in(); _rep(curCase,1,testCnt)
#ifdef ONLINE_JUDGE
#define debug(...) 0
#else
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#endif
#define pc __builtin_popcount
using ll = long long;
using pii = pair<int,int>;
#define link asfg
int in(void) { int x; scanf("%d", &x); return x; } ll inl(void) { ll x; scanf("%lld", &x); return x; }
void out(int x) { printf("%d ", x); } void outln(int x) { printf("%d\n", x); }
void out(ll x) { printf("%lld ", x); } void outln(ll x) { printf("%lld\n", x); }
template<typename T> void chkmax(T &a, const T &b) { a = max(a, b); } 
template<typename T> void chkmin(T &a, const T &b) { a = min(a, b); } 
const int kN = 205000;
// int mu[kN], pri[kN], prime[kN], pcnt;
char s[kN]; int n;

struct SuffixArray {
	int sa[kN], x[kN], y[kN], rk[kN], cnt[kN], h[18][kN];
	void suffix_sort(char *s) {
		x[n + 1] = y[n + 1] = 0;
		int m = 500;
		_rep(i,1,m) cnt[i] = 0;
		_rep(i,1,n) ++cnt[x[i] = s[i]];
		_rep(i,1,m) cnt[i] += cnt[i - 1];
		_rep(i,1,n) sa[cnt[x[i]]--] = i;
		for(int k = 1; k <= n; k <<= 1) {
			int top = 0;
			_rep(i,n - k + 1, n) y[++top] = i;
			_rep(i,1,n) if(sa[i] > k) y[++top] = sa[i] - k;
			_rep(i,1,m) cnt[i] = 0;
			_rep(i,1,n) ++cnt[x[i]];
			_rep(i,1,m) cnt[i] += cnt[i - 1];
			for(int i = n; i; --i) sa[cnt[x[y[i]]]--] = y[i], y[i] = 0;
			swap(x, y);
			x[sa[1]] = m = 1;
			_rep(i,2,n) if(y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k])
				x[sa[i]] = m; else x[sa[i]] = ++m;
		}
		_rep(i,1,n) rk[sa[i]] = i;
		int tmp = 0;
		_rep(i,1,n) {
			if(rk[i] == 1) continue;
			if(tmp) --tmp;
			while(s[i + tmp] == s[sa[rk[i] - 1] + tmp]) ++tmp;
			h[0][rk[i]] = tmp;
		}
		_rep(i,1,17) _rep(j,2,n - (1 << i) + 1) h[i][j] = min(h[i - 1][j], h[i - 1][j + (1 << i - 1)]);
	}
	int LCP(int i, int j) {
		if(i == j) return n - i + 1;
		int a = rk[i], b = rk[j];
		if(a > b) swap(a, b);
		int k = __lg(b - a);
		return min(h[k][a + 1], h[k][b - (1 << k) + 1]);
	}
} sa, as;
 
int ch[kN << 1][26], len[kN << 1], link[kN << 1], endpos[kN << 1], nc, last;
int clone(int x) { return ++nc, memcpy(ch[nc], ch[x], sizeof(ch[nc])), link[nc] = link[x], endpos[nc] = endpos[x], nc; }
void extend(char c, int a) { c -= 'a';
	int cur = ++nc; len[cur] = len[last] + 1, endpos[cur] = a;  memset(ch[cur], 0, sizeof(ch[cur]));
	while(~last && !ch[last][c]) ch[last][c] = cur, last = link[last];
	if(last == -1) link[cur] = 0;
	else {
		int p = ch[last][c];
		if(len[p] == len[last] + 1) link[cur] = p;
		else {
			int q = clone(p); len[q] = len[last] + 1;
			while(~last && ch[last][c] == p) ch[last][c] = q, last = link[last];
			link[cur] = link[p] = q;
		}
	} last = cur;
}
vector<int> nodes[kN];
vector<pii> scan[kN];

int lp[kN << 2];
void build(int x, int L, int R) {
	lp[x] = 1e9;
	if(L == R) return;
	build(x << 1, L, mid), build(x << 1 | 1, mid + 1, R);
}
void modify(int x, int L, int R, int p, int y) {
	if(L == R) {
		if(y < 0 && lp[x] == -y) lp[x] = 1e9;
		if(y > 0) lp[x] = y;
		return;
	}
	p <= mid ? modify(x << 1, L, mid, p, y) : modify(x << 1 | 1, mid + 1, R, p, y);
	lp[x] = min(lp[x << 1], lp[x << 1 | 1]);
}
pii query(int x, int L, int R, int p) {
	if(lp[x] > p) return make_pair(-1, -1);
	if(L == R) return make_pair(L, lp[x]);
	pii v = query(x << 1, L, mid, p);
	if(v != make_pair(-1, -1)) return v;
	return query(x << 1 | 1, mid + 1, R, p);
}
pii yreuq(int x, int L, int R, int p) {
	if(lp[x] > p) return make_pair(-1, -1);
	if(L == R) return make_pair(L, lp[x]);
	pii v = yreuq(x << 1 | 1, mid + 1, R, p);
	if(v != make_pair(-1, -1)) return v;
	return yreuq(x << 1, L, mid, p);
}
int main() {
	// freopen("string.in", "r", stdin);
	// freopen("string.out", "w", stdout);
	// mu[1] = 1; int N = 200000;
	// _rep(i,2,N) {
	// 	if(!pri[i]) prime[++pcnt] = i, mu[i] = -1;
	// 	for(int j = 1; j <= pcnt && i * prime[j] <= N; ++j) {
	// 		if(i % prime[j] == 0) {
	// 			mu[i * prime[j]] = 0;
	// 			pri[i * prime[j]] = 1;
	// 			break;
	// 		}
	// 		mu[i * prime[j]] = -mu[i];
	// 		pri[i * prime[j]] = 1;
	// 	}
	// }
	// _rep(i,1,10) debug("%d%c", mu[i], " \n"[i == 10]);
	multiCase() {
		// clock_t st = clock();
		scanf("%s", s + 1);
		n = strlen(s + 1);
		// suffix_sort();
		sa.suffix_sort(s);
		reverse(s + 1, s + 1 + n);
		as.suffix_sort(s);
		reverse(s + 1, s + 1 + n);
		nc = last = 0, memset(ch[0], 0, sizeof(ch[0])), len[0] = 0, link[0] = -1;
		_rep(i,1,n) extend(s[i], i); 
		_rep(i,1,n) nodes[i].clear();
		_rep(i,1,nc) nodes[endpos[i]].emplace_back(i);
		
		_rep(i,1,n) scan[i].clear();
		_rep(a,1,n) {
			// int lastr = -1;
			for(int l = 1, r = a + 1; r <= n; l += a, r += a) {
				int lft = as.LCP(n - l + 1, n - r + 1), rgt = sa.LCP(l, r);
				// debug("a = %d, l = %d, r = %d, lft = %d, rgt = %d\n", a, l, r, lft, rgt);
				if(rgt > a || lft + rgt - 1 < a) continue;
				int L = l - lft + 1, R = r + rgt - 1;
				scan[L + 2 * a - 1].emplace_back(a, L);
				scan[R + 1].emplace_back(a, -L);
				// lastr = R;
				// debug("Find [%d, %d], period = %d\n", L, R, a);
			}
		}
		// _rep(i,1,n) sort(scan[i].begin(), scan[i].end(), [](const pii &a, const pii &b) {
			// return a.second < b.second;
		// });
		ll ans = 0;
		_rep(i,1,nc) ans += len[i] - len[link[i]];
		// debug("ans = %lld\n", ans);
		build(1, 1, n);
		_rep(r,1,n) {
			// debug("r = %d\n", r);
			for(auto &[a, b] : scan[r]) modify(1, 1, n, a, b); //, debug("MODIFY %d %d\n", a, b);
			for(auto &u : nodes[r]) {
				auto [period, pos] = query(1, 1, n, r - len[link[u]]);
				if(period == -1) continue;
				// debug("Node %d gets %d, %d %d\n", u, period, pos, r - pos + 1);
				ans -= min(len[u], r - pos + 1) / period - len[link[u]] / period;
				if(len[link[u]] < period && period <= min(len[u], r - pos + 1)) ++ans;
				auto [p2, po2] = yreuq(1, 1, n, r - len[link[u]]);
				if(p2 != -1 && p2 % period != 0) {
					ans -= min(len[u], r - po2 + 1) / p2 - len[link[u]] / p2;
					if(len[link[u]] < p2 && p2 <= min(len[u], r - po2 + 1)) ++ans;
				}
				// debug("ans = %lld\n", ans);
			}	
		}
		outln(ans);
		// debug("single test case time = %.2lf\n", (clock() - st) * 1. / CLOCKS_PER_SEC);
		// int x, y;
		// while(1) {
		// 	x = in(), y = in();
		// 	if(!x && !y) break;
		// 	outln(LCP(x, y));
		// }
	}
	return 0;
}

这程序好像有点Bug,我给组数据试试?

详细

Test #1:

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

input:

6
rikkasuggeststoallthecontestants
thisisaproblemdesignedforgrandmasters
ifyoudidnotachievethat
youdbetterskiptheproblem
wishyouahighrank
enjoytheexperience

output:

500
679
244
290
132
163

result:

ok 6 lines

Test #2:

score: 0
Accepted
time: 4443ms
memory: 120680kb

input:

1000
mxsslrrxtwwnwlsrxxxbsmtxxwwntsbrwlxnbxunutnlmrrlubturuwmbnobrolwunwurtbnmlumxmwtwrsulruxslsnltsstmmxbsmuonroubrnnmu
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
glggglgg
yykkyyyykykykyyyykyykykkkyyyykkyykkkyyykykyykyyykkykky...

output:

6522
1
20
9443
11294
1
8619
26
7898
260905
9048
6
22114
52
20
45
7
39
10
1
28
26
10
47
32
12977
30
13
7473
12
8402
1
8083
16
1
10462
16
9278
1
1
8968
7858
11148
8130
6
8516
12223
9266
8374
26
45
14
10150
9
10175
298758
203677
11522
12
8985
10687
12
1
6613277686
10
10
1
5794
28
1
280529
7874
13
10564...

result:

ok 1000 lines

Test #3:

score: 0
Accepted
time: 3954ms
memory: 109368kb

input:

26
hihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihh...

output:

9523687993
9529757593
9537405289
9539347561
9533035177
9528058105
564250
9522959641
9542382361
9518953705
9519439273
9534977449
9519803449
9535705801
9519560665
9534249097
9527572537
9523687993
9539468953
9532064041
9525873049
9532185433
9541168441
9524901913
9531092905
9518832313

result:

ok 26 lines

Test #4:

score: 0
Accepted
time: 3995ms
memory: 109908kb

input:

26
oohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohooh...

output:

9625902365
9628810517
9622671085
9626467839
9628891299
9626306275
9630668503
9620409189
9618228075
9622428739
9628406607
9625336891
9630426157
9626871749
9620086061
9626144711
9616935563
9617177909
9626790967
9627194877
9626467839
354971
9616370089
9618308857
9617824165
9616773999

result:

ok 26 lines

Test #5:

score: 0
Accepted
time: 3943ms
memory: 109784kb

input:

26
vggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvg...

output:

13085098340
13073668733
13071665606
13067070197
13077910649
13074964874
13078735466
13070840789
13072726085
13067895014
669720
13065891887
13065302732
13076496677
13068484169
13064242253
13065420563
13063181774
13080502931
13067070197
13072490423
13070015972
13083802199
13064831408
13075671860
13085...

result:

ok 26 lines