这个题跟 C Q O I 2015 CQOI2015 CQOI2015任务查询系统是一样的
查询区间前 k k k大的权值和
大概上板子就够了… 注意开 l o n g l o n g long long longlong
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;
}