谁帮我卡卡常
查看原帖
谁帮我卡卡常
939431
szh_AK_alldevotion楼主2024/7/27 21:32

谁帮我卡卡常啊,分块一直超时。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n, m;
int b = 100;
int L[1000005], R[1000005], pos;
int pr[1000005], la[1000005], c[1000005], a[1000005];

inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}
	return x * f;
}

inline void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

inline void undate(const int x, const int z) {
	for (int i = 1; i <= n; i++)
		la[a[i]] = 0;
	a[x] = z;
	for (int i = 1; i <= pos; i++) {
		int p = 0;
		for (int j = L[i]; j <= R[i]; j++) {
			int tmp = pr[j];
			pr[j] = la[a[j]];
			if (pr[j] != tmp)
				p = 1;
			la[a[j]] = j;
		}
		if (p) {
			int l = L[i], r = R[i];
			for (int j = l; j <= r; j++)
				c[j] = pr[j];
			sort(c + l, c + r + 1);
		}
	}
}

inline int er(const int x, const int z) {
	int l = L[x], r = R[x];
	while (l <= r) {
		int mid = (l + r) / 2;
		if (c[mid] < z)
			l = mid + 1;
		else
			r = mid - 1;
	}
	return l - L[x];
}

inline int ask(const int l, const int r) {
	int ll = (l - 1) / b + 1, rr = (r - 1) / b + 1, ans = 0;
	if (r - l + 1 <= 2 * b) {
		for (int i = l; i <= r; i++)
			if (pr[i] < l)
				ans++;
		return ans;
	}
	if (l == L[ll])
		ll--;
	if (r == R[rr])
		rr++;
	for (int i = l; i <= R[ll]; i++)
		if (pr[i] < l)
			ans++;
	for (int i = L[rr]; i <= r; i++)
		if (pr[i] < l)
			ans++;
	for (int i = ll + 1; i < rr; i++)
		ans += er(i, l);
	return ans;
}

int main() {
	n = read(), m = read();
	for (int i = 1; i <= n; i++)
		a[i] = read();
	for (int i = 1; i <= n; i++) {
		if (i % b == 1) {
			L[++pos] = i;
			R[pos - 1] = i - 1;
		}
	}
	R[pos] = n;
	L[pos + 1] = R[pos + 1] = n + 1;
	for (int i = 1; i <= n; i++) {
		pr[i] = la[a[i]];
		la[a[i]] = i;
	}
	for (int i = 1; i <= pos; i++) {
		int l = L[i], r = R[i];
		for (int j = l; j <= r; j++)
			c[j] = pr[j];
		sort(c + l, c + r + 1);
	}
	while (m--) {
		char op;
		int l, r;
		while ((op = getchar()) != 'Q' && op != 'R');
		l = read(), r = read();
		if (op == 'Q')
			write(ask(l, r)), puts("");
		else
			undate(l, r);
	}
}
2024/7/27 21:32
加载中...