求助
查看原帖
求助
336744
团队官方账号楼主2020/5/24 10:27

这道题是昨天code+7的第4题,蒟蒻听大佬讲的,可还是不懂。

#include <bits/stdc++.h>
using namespace std;
int n, m, mn[100010], lg[100010], st[20][100010];
int c[100010], l[1000010], r[1000010];
vector<int> M[1000010];
void add(int p) {
	for (; p <= n; p += p & -p) c[p]++;
}
int sum(int p) {
	int s = 0;
	for (;p; p -= p & -p) s += c[p];
	return s;
}
int main() {
	scanf("%d %d", &n, &m);
	memset(mn, 0x3f, sizeof(mn));
	for (int i = 1, op, x, y; i <= m; i++) {
		scanf("%d %d", &op, &x);
		if (op == 1) {
			if (mn[x] < 1e9) continue;
			mn[x] = i;
		} else {
			scanf("%d", &y);
			l[i] = x, r[i] = y;
		}
	}
	for (int i = 1; i <= n; i++) {
		st[0][i] = mn[i];
		if (i > 1) lg[i] = lg[i >> 1] + 1;
	}
	for (int i = 1; i < 20; i++) {
		for (int j = 1; j + (1 << i) - 1 <= n; j++) {
			st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
		}
	}
	auto query = [&](int l, int r) {
		int k = lg[r - l + 1];
		return min(st[k][l], st[k][r - (1 << k) + 1]);
	};
	for (int i = 1; i <= n; i++) {
		int mx = 0;
		for (int l = 1; l <= n; l += i) {
			int r = min(n, l + i - 1);
			mx = max(mx, query(l, r));
			if (mx > 1e9) break;
			M[mx].push_back(i);
		}
	}
	for (int i = 1; i <= n; i++) add(i);
	for (int i = 1; i <= m; i++) {
		for (int j : M[i]) add(j);
		if (l[i]) printf("%d\n", sum(r[i]) - sum(l[i] - 1));
	}
	return 0;
}
2020/5/24 10:27
加载中...