QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#479014#6509. Not Another Range Query ProblempavementWA 15ms35400kbC++174.4kb2024-07-15 13:57:112024-07-15 13:57:11

Judging History

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

  • [2024-07-15 13:57:11]
  • 评测
  • 测评结果:WA
  • 用时:15ms
  • 内存:35400kb
  • [2024-07-15 13:57:11]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using ii = pair<int, int>;
using iii = tuple<int, int, int>;

#define pb push_back
#define eb emplace_back
#define mp make_pair

int n, q, ans[500005], del_time[500005], ft[500005];
char s[500005];
vector<iii> qu[500005], qu2[500005];
set<int> rem;

int ls(int x) {
	return x & -x;
}

void ft_upd(int p) {
	for (; p <= n; p += ls(p)) {
		ft[p]++;
	}
}

int ft_qry(int p) {
	int r = 0;
	for (; p; p -= ls(p)) {
		r += ft[p];
	}
	return r;
}

struct dat {
	int a{-1}, b{-1}, diff{(int)1e9};
};

dat combine(dat lhs, dat rhs) {
	dat ret;
	ret.diff = min(lhs.diff, rhs.diff);
	if (lhs.b != -1 && rhs.a != -1 && s[lhs.b] != s[rhs.a]) {
		ret.diff = min(ret.diff, rhs.a);
	}
	if (lhs.a == -1) {
		ret.a = rhs.a;
	} else {
		ret.a = lhs.a;
	}
	if (rhs.b == -1) {
		ret.b = lhs.b;
	} else {
		ret.b = rhs.b;
	}
	return ret;
}

struct node {
	node *left, *right;
	int S, E;
	dat val;
	node(int _s, int _e) : S(_s), E(_e) {
		if (S == E) {
			val.a = val.b = S;
			return;
		}
		int M = (S + E) / 2;
		left = new node(S, M);
		right = new node(M + 1, E);
		val = combine(left->val, right->val);
	}
	dat qry(int l, int r) {
		if (l > E || r < S) {
			dat dummy;
			return dummy;
		}
		if (l <= S && E <= r) {
			return val;
		}
		return combine(left->qry(l, r), right->qry(l, r));
	}
	void del(int p) {
		if (S == E) {
			val.a = val.b = -1;
			val.diff = (int)1e9;
			return;
		}
		int M = (S + E) / 2;
		if (p <= M) {
			left->del(p);
		} else {
			right->del(p);
		}
		val = combine(left->val, right->val);
	}
} *root;

struct node2 {
	node2 *left, *right;
	int S, E, actives, pv;
	ii val;
	node2(int _s, int _e) : S(_s), E(_e), actives(0), pv(0), val((int)1e9, -1) {
		if (S == E) {
			return;
		}
		int M = (S + E) / 2;
		left = new node2(S, M);
		right = new node2(M + 1, E);
	}
	void prop() {
		left->val.first += pv;
		left->pv += pv;
		right->val.first += pv;
		right->pv += pv;
		pv = 0;
	}
	void activate(int p, int v) {
		if (S == E) {
			val = mp(v, p);
			actives++;
			return;
		}
		prop();
		int M = (S + E) / 2;
		if (p <= M) {
			left->activate(p, v);
		} else {
			right->activate(p, v);
		}
		val = min(left->val, right->val);
		actives = left->actives + right->actives;
	}
	void del(int p) {
		if (S == E) {
			val = mp((int)1e9, -1);
			actives--;
			return;
		}
		prop();
		int M = (S + E) / 2;
		if (p <= M) {
			left->del(p);
		} else {
			right->del(p);
		}
		val = min(left->val, right->val);
		actives = left->actives + right->actives;
	}
	void upd(int l, int r, int v) {
		if (l > E || r < S) {
			return;
		}
		if (l <= S && E <= r) {
			val.first += v;
			pv += v;
			return;
		}
		prop();
		left->upd(l, r, v);
		right->upd(l, r, v);
		val = min(left->val, right->val);
	}
	int kth(int k) {
		if (S == E) {
			return S;
		}
		prop();
		if (left->actives >= k) {
			return left->kth(k);
		} else {
			return right->kth(left->actives);
		}
	}
} *root2;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> q;
	for (int i = 1; i <= n; i++) {
		cin >> s[i];
	}
	root = new node(1, n);
	for (int i = 1; i <= n; i++) {
		rem.insert(i);
	}
	for (int t = 1; !rem.empty(); t++) {
		vector<int> to_erase;
		for (int st = *rem.begin(); st <= n; st = root->qry(st, n).diff) {
			to_erase.pb(st);
		}
		for (auto i : to_erase) {
			rem.erase(i);
			root->del(i);
			del_time[i] = t;
		}
	}
	for (int i = 1, l, r, k; i <= q; i++) {
		cin >> l >> r >> k;
		qu[l].eb(r, k, i);
	}
	root2 = new node2(1, n);
	for (int l = n; l >= 1; l--) {
		root2->activate(l, del_time[l] + root2->actives);
		assert(root2->val.first >= root2->actives - 1);
		if (root2->val.first == root2->actives - 1) {
			// remove root2->val.second
			int x = root2->val.second;
			root2->del(x);
			root2->upd(1, x, -1);
		}
		for (auto [r, k, idx] : qu[l]) {
			int lim;
			if (k == 0) {
				lim = l;
			} else if (k <= root2->actives) {
				lim = root2->kth(k) + 1;
			} else {
				lim = r + 1;
			}
			// [lim, r]
			if (lim <= r) {
				qu2[lim].eb(1, k, idx);
				if (r + 1 <= n) {
					qu2[r + 1].eb(-1, k, idx);
				}
			}
		}
	}
	for (int l = n; l >= 1; l--) {
		ft_upd(del_time[l]);
		for (auto [coeff, k, idx] : qu2[l]) {
			ans[idx] += coeff * (n - l + 1 - ft_qry(k));
		}
	}
	for (int i = 1; i <= q; i++) {
		cout << ans[i] << '\n';
	}
}

詳細信息

Test #1:

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

input:

9 7
100110001
2 5 1
3 6 1
4 8 2
2 7 1
1 9 1
1 9 0
1 9 8

output:

2
1
1
3
4
9
0

result:

ok 7 numbers

Test #2:

score: -100
Wrong Answer
time: 15ms
memory: 35400kb

input:

100 100000
0000011010101000111011110110000111110101101010111111101011011010111001111010111000001000011000001010
76 99 3
25 84 7
45 83 11
10 12 10
69 86 4
27 28 1
22 42 42
4 86 25
26 91 22
20 81 17
50 78 0
77 93 50
31 50 34
7 46 13
78 89 0
79 98 0
2 84 33
58 93 11
56 75 2
55 77 68
7 9 41
44 46 11
47 ...

output:

18
16
6
0
11
1
0
0
0
0
29
0
0
0
12
20
0
10
8
0
0
0
0
0
0
0
0
6
18
17
0
57
0
0
11
0
13
0
0
0
0
0
0
0
0
4
0
0
3
0
3
2
0
0
21
0
0
0
16
6
0
0
0
0
2
0
0
16
14
0
0
0
5
0
15
3
1
17
0
21
29
40
22
16
26
0
21
6
0
11
18
8
0
7
3
0
0
0
4
0
5
0
51
0
0
8
24
21
0
22
10
9
16
0
16
22
0
22
0
27
0
0
0
0
0
0
10
46
59
2
...

result:

wrong answer 1st numbers differ - expected: '8', found: '18'