1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
| // Code By Chen Qiqian on 2018.10.16
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 210000;
int n,m;
struct Node{
ll d,p,l;
bool operator < (const Node &a)const{
if(d != a.d)
return d > a.d;
else
return p < a.p;
}
}t[MAXN];
bool cmp(const int &a,const int &b){
if(t[a].p != t[b].p)
return t[a].p < t[b].p;
else
return t[a].l < t[b].l;
}
struct Query{
ll g,l,id;
}q[MAXN];
int ans[MAXN];
void init(){
scanf("%d %d",&n,&m);
for(int i = 1;i<=n;i++){
ll a,b,c;
scanf("%lld %lld %lld",&a,&b,&c);
t[i] = (Node){a,b,c};
}
sort(t+1,t+n+1);
for(int i = 1;i<=m;i++){
scanf("%lld %lld",&q[i].g,&q[i].l);
q[i].id = i;
}
}
int a1[MAXN],a2[MAXN];
struct T{
ll p,l;
bool operator < (const T &w)const{
if(p != w.p)
return p < w.p;
else
return l < w.l;
}
};
multiset<T> K;
int pos = 0;//[1,pos]
bool cmp2(const int a,const int b){
return q[a].g < q[b].g;
}
void solve(int *a,int n1,int l,int r){// *a 存储询问编号 在 [l,r] 果汁内二分
if(n1 == 0) return;
if(l == r){
for(int i = 0;i<n1;i++)
ans[q[a[i]].id] = t[l].d;
return;
}
// 寻找到最小的需要的 n
// d 按从大到小排序
int mid = (l+r)>>1;
//判断 1 -> mid 区间是否可以满足限制 (g_i,l_i)
//维护multiset使其可以包括 [1,mid] 所有果汁
while(pos < mid){
pos++;
K.insert((T){t[pos].p,t[pos].l});
}
while(pos > mid){
K.erase(K.lower_bound((T){t[pos].p,t[pos].l}));
pos--;
}
ll G = 0,L = 0,acnt = 0,bcnt = 0;
sort(a,a+n1,cmp2);
multiset<T>::iterator it = K.begin();
#define xp it->p
#define xl it->l
for(int i = 0;i<n1;i++){
while(it != K.end() && G + xp * xl <= q[a[i]].g){
G += xp * xl,L += xl;
it++;
}
if(L >= q[a[i]].l ||
(it != K.end() && (q[a[i]].l-L) * xp + G <= q[a[i]].g))
a1[acnt++] = a[i];
else
a2[bcnt++] = a[i];
}
memcpy(a,a1,sizeof(int)*acnt),memcpy(a+acnt,a2,sizeof(int)*bcnt);
solve(a,acnt,l,mid),solve(a+acnt,bcnt,mid+1,r);
#undef xp
#undef xl
}
void solve(){
static int qq[MAXN];
for(int i = 1;i<=m;i++)
qq[i] = i;
t[n+1].d=-1;t[n+1].p=0;t[n+1].l=1e18;++n;
solve(qq+1,m,1,n);
for(int i = 1;i<=m;i++)
printf("%d\n",ans[i]);
}
signed main(){
init();
solve();
return 0;
}
|