Loading

2019ICPC徐州 H.Yuuki and a problem

给一个序列

要支持两个操作

  1. 修改 \(A[x] = y\)
  2. 区间询问 \([L,R]\) 中最小的不能被表示为 \([L,R]\) 中子集合 \((subset)\) 的和 正整数

首先要明白的几件事情是

首先用一个桶装每个值的和

  • 如果没有 \(1\) 的话,答案就是 \(1\)
  • 若现在能凑成 \([1,sum]\) ,如果再来一个 \(sum+1\) ,就可以凑成 \([1,2sum+1]\)
  • 最开始有 \(x\)\(1\) 的话,可以凑成 \([1,x]\) ,我们计算 \(X = \sum_{i=1}^{x+1}sum_i\) ,

若数字 \(x\) 出现 \(k\) 次 , 则 \(sum_x = kx\) 。 若 \(X = x\) ,则答案就是 \(x+1\)

这样迭代,速度很快

然后数据结构上,用树状数组套一个权值线段树就可以。

树状数组维护了前缀和信息,可以进行区间内的查询。

#include<bits/stdc++.h>
typedef long long ll;
#define mid (l+r>>1)
#define min(a,b) (a<b?a:b)
using namespace std;

const int N = 2e5 + 10;

ll sum[N * 100];int Lc[N * 100], Rc[N * 100], tot;

void insert(int& rt, int l, int r, int val, int pos) {
	if (!rt)rt = ++tot;
	sum[rt] += val;
	if (l == r)return;
	if (pos <= mid)insert(Lc[rt], l, mid, val, pos);
	else insert(Rc[rt], mid + 1, r, val, pos);
}

ll query(int rt, int l, int r, int L, int R) {
	if (!rt) return 0;
	if (L <= l and r <= R)return sum[rt];
	ll ans = 0;
	if (L <= mid)ans += query(Lc[rt], l, mid, L, R);
	if (R > mid) ans += query(Rc[rt], mid + 1, r, L, R);
	return ans;
}

int lowbit(int x) { return x & (-x); }
int root[N];
const int M = N - 1;
void insert(int pos, int ppos, int val) {
	for (int i = pos; i <= M; i += lowbit(i)) {
		insert(root[i], 1, M, val, ppos);
	}
}
ll query(int l, int r, int L, int R) {
	ll ans = 0;
	for (int i = r; i; i -= lowbit(i)) {
		ans += query(root[i], 1, M, L, R);
	}
	for (int i = l - 1; i; i -= lowbit(i)) {
		ans -= query(root[i], 1, M, L, R);
	}
	return ans;
}

int n, q;
int A[N];
signed main() {
	scanf("%d%d", &n, &q);
	for (int i = 1; i <= n; i++) {
		scanf("%d", A + i);
		insert(i, A[i], A[i]);
	}
	while (q--) {
		int op, a, b; scanf("%d%d%d", &op, &a, &b);
		if (op == 1) {
			insert(a, A[a], -A[a]);
			A[a] = b;
			insert(a, A[a], A[a]);
		}
		else {
			ll sum = query(a, b, 1, 1);
			if (!sum) puts("1");
			else {
				ll last = sum;
				while (1) {
					sum = query(a, b, 1, min(last + 1, M));
					if (sum == last)break;
					last = sum;
				}
				printf("%lld\n", last + 1);
			}
		}
	}
}
posted @ 2020-11-04 12:11  —O0oO-  阅读(172)  评论(0编辑  收藏  举报