分块只能过样例|求调
查看原帖
分块只能过样例|求调
743373
Vitamin_B楼主2024/7/7 17:16

rt,https://www.luogu.com.cn/record/164450156,样例AC,die码如下:

// # pragma GCC optimize("Ofast,no-stack-protector")
//
// # pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

# include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair <int, int> pii;

int n, m, k, l, r, t, col[500005], st[705], ed[705], have[705], a[500005];

char op;

ll s[705];

bitset <500005> vis;

void init () {

	n = 500000;

	t = sqrt (n);

	for (int i = 1; i <= t; ++ i)
		st[i] = n / t * (i - 1) + 1, ed[i] = n / t * i;

	ed[t] = n;

	for (int i = 1; i <= t; ++ i)
		for (int j = st[i]; j <= ed[i]; ++ j)
			col[j] = i, s[i] += a[j], have[i] += vis[j];

	return ;

}

void change (int x, int y) {

	s[col[x]] -= y;

	a[x] -= y;

	return ;

}

void add (int x, int y) {

	if (vis[x])
		s[col[x]] += y - a[x], a[x] = y;
	else
		vis[x] = 1, s[col[x]] += y, a[x] = y, ++ have[col[x]];

	return ;

}

void del (int x) {

	int c = 1;

	while (x > have[c])
		x -= have[c], ++ c;

	for (int i = st[c]; i <= ed[c]; ++ i)
		if (vis[i])
			if (x > 1)
				-- x;
			else {

				-- have[c];

				s[c] -= a[i];

				vis[i] = 0;

				a[i] = 0;

				return ;

			}
//	cerr << "-1\n";
	return ;

}

ll find () {

	ll sum = 0;

	for (int i = col[1]; i <= col[n]; ++ i)
		sum += s[i];

	return sum;

}

int main () {

	ios::sync_with_stdio (0);

	cin.tie (0);

	cout.tie (0);

	cin >> n >> m;

	for (int i = 1; i <= n; ++ i)
		cin >> a[i], vis[i] = 1;

	init ();

	while (m --) {

		cin >> op;

		if (op == 'C')
			cin >> l >> r, change (l, r);
		else if (op == 'I')
			cin >> l >> r, add (l, r);
		else if (op == 'D')
			cin >> l, del (l);
		else
			cout << find () << '\n';

	}

	return 0;

}
2024/7/7 17:16
加载中...