新型做法之 O(nlogn)多次二分查找
查看原帖
新型做法之 O(nlogn)多次二分查找
1054952
jinxiu6_hehe楼主2025/2/8 15:19
#include <bits/stdc++.h>
//#define qwq puts("qwq");

using namespace std;

const int N = 1100000, M = 2100000;
bool mmp[M];
int n, q, tx, ty, s[N], c[N], mp[M];
char ch[N];

int main() {
	scanf("%d%d%s", &n, &q, ch + 1);
	for (int i = 1; i <= n; i++) {
		s[i] = s[i - 1] + (ch[i] == 'T' ? 2 : 1);
		if (ch[i] == 'T' && !ty)
			ty = i;
		if (ch[i] == 'W' && !tx)
			tx = i;
		mmp[s[i]] = true;
		mp[s[i]] = i;
	}
	for (int i = 2; i <= n; i++)
		c[i] = c[i - 1] + ((s[i] - s[i - 1]) & 1);
//	for (int i = 1; i <= n; i++)
//		printf("%d ", s[i]);
//	puts("");
//	for (int i = 1; i <= n; i++)
//		printf("%d ", c[i]);
//	puts("");
	for (int i = 1; i <= q; i++) {
		if (i != 1)
			puts("");
		int x;
		scanf("%d", &x);
		if (mmp[x]) {
			printf("1 %d", mp[x]);
			continue;
		}
		if (x <= 2) {
			if (x == 1) {
				if (tx)
					printf("%d %d", tx, tx);
				else
					printf("NIE");
			} else	{
				if (ty)
					printf("%d %d", ty, ty);
				else {
					if (n >= 2)
						printf("1 2");
					else
						printf("NIE");
				}
			}
			continue;
		}
		x += s[1];
		int l = 0, r = n;
		while (l + 1 < r) {
			int m = (l + r) / 2;
			if (x <= s[m])
				r = m;
			else
				l = m;
		}
		if (x > s[r]) {
			printf("NIE");
			continue;
		}
		if (x == s[r]) {
			printf("%d %d", 2, r);
			continue;
		}
		r--;
		if (c[n - r + 1] + c[n] - c[r - 1] > 0) {
			int ll = 1, rr = r - 1;
			while (ll + 1 < rr) {
				int m = (ll + rr) / 2;
				if (c[m] > 0)
					rr = m;
				else
					ll = m;
			}
			if (c[rr] == 0)
				rr = 1 << 30;
			int lll = r, rrr = n;
			while (lll + 1 < rrr) {
				int m = (lll + rrr) / 2;
				if (c[m] - c[r] > 0)
					rrr = m;
				else
					lll = m;
			}
			if (c[rrr] - c[r] == 0)
				rrr = 1 << 30;
			if (rrr - r <= rr - 1)
				printf("%d %d", rrr - r + 1, rrr);
			else
				printf("%d %d", rr + 1, r + rr - 1);
		} else
			printf("NIE");
	}
	return 0;
}
/*
7 3
TTWWTWT
5
7
4

10 5
TWTTWWWTTT
7
1
2
11
8
*/
2025/2/8 15:19
加载中...