#LOJ2555. 「CTSC2018」混合果汁 主席树

版权声明:_ https://blog.csdn.net/lunch__/article/details/82712178

题面

这个题跟 C Q O I 2015 CQOI2015 任务查询系统是一样的

查询区间前 k k 大的权值和

大概上板子就够了… 注意开 l o n g l o n g long long

Codes

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e5 + 10;

int n, m, root[N];

struct node {
	int d, p, l;
}A[N];

bool cmp(node X, node Y) {return X.d < Y.d;}

struct Chairman_Tree {
#define ls(x) (T[x].ch[0])
#define rs(x) (T[x].ch[1])
#define mid ((l + r) >> 1)

	int cnt;
	struct node {
		int ch[2]; ll sum, Sum;
	}T[N << 6];

	void build(int &x, int l, int r) {
		x = ++ cnt; if(l != r) build(ls(x), l, mid), build(rs(x), mid + 1, r);
	}

	void update(int &x, int pre, int l, int r, int p, int v) {
		T[x = ++ cnt] = T[pre]; T[x].sum += v, T[x].Sum += 1ll * p * v;
		if(l == r) return;
		if(p <= mid) update(ls(x), ls(pre), l, mid, p, v);
		else update(rs(x), rs(pre), mid + 1, r, p, v);
	}

	ll query(int x, int pre, int l, int r, ll k) {
		if(k > T[x].sum - T[pre].sum) return 1e18;
		if(l == r) return 1ll * l * k;
		if(k <= T[ls(x)].sum - T[ls(pre)].sum) return query(ls(x), ls(pre), l, mid, k);
		return T[ls(x)].Sum - T[ls(pre)].Sum + query(rs(x), rs(pre), mid + 1, r, k - (T[ls(x)].sum - T[ls(pre)].sum));
	}

}T;

int main() {
#ifndef ONLINE_JUDGE
	freopen("2555.in", "r", stdin);
	freopen("2555.out", "w", stdout);
#endif
	ll x, y;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++ i)
		scanf("%d%d%d", &A[i].d, &A[i].p, &A[i].l);
	sort(A + 1, A + n + 1, cmp);
	T.build(root[0], 1, 1e5);
	for(int i = 1; i <= n; ++ i) 
		T.update(root[i], root[i - 1], 1, 1e5, A[i].p, A[i].l);
	while(m --) {
		scanf("%lld%lld", &x, &y);
		int l = 1, r = n, ans = -1; 
		while(l <= r) {
			if(T.query(root[n], root[mid - 1], 1, 1e5, y) <= x)
				ans = A[mid].d, l = mid + 1;
			else r = mid - 1;
		}
		printf("%d\n", ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/lunch__/article/details/82712178