Description
Data Constraint
Solution
可以发现,对于某个询问,开张时间超过计划的是没有贡献的,显然就可以通过以时间为第一关键字排序,用个指针添加有贡献的商店。分析数据后发现,总价值最大不超过9000。设 fi 为当答案为i时,需要花费 fi 的价值,设 gi 为 min(gi,gi+1,gi+2,……) ,得到了这样的一个g数组后,我们就可以二分了:对于每一次二分出的mid,判断一下 gmid 是否小于等于计划的预算,如果是则符合要求。
Code
var
f,g:array[0..100000] of longint;
a:array[0..305,1..3] of longint;
q:array[0..100000,1..3] of longint;
ans:array[0..100000] of longint;
n,m,i,j,mx,maxn,l,r,mid:longint;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure qsort1(l,r:longint);
var i,j,mid:longint;
begin
i:=l;j:=r;
mid:=a[(i+j)div 2,3];
repeat
while a[i,3]<mid do inc(i);
while mid<a[j,3] do dec(j);
if i<=j then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
inc(i); dec(j);
end;
until i>j;
if i<r then qsort1(i,r);
if l<j then qsort1(l,j);
end;
procedure qsort2(l,r:longint);
var i,j,mid:longint;
begin
i:=l;j:=r;
mid:=q[(i+j)div 2,1];
repeat
while q[i,1]<mid do inc(i);
while mid<q[j,1] do dec(j);
if i<=j then
begin
q[0]:=q[i];q[i]:=q[j];q[j]:=q[0];
inc(i); dec(j);
end;
until i>j;
if i<r then qsort2(i,r);
if l<j then qsort2(l,j);
end;
begin
readln(n,m);
for i:=1 to n do
begin
readln(a[i,1],a[i,2],a[i,3]);
maxn:=maxn+a[i,2];
end;
for i:=1 to m do
begin
readln(q[i,1],q[i,2]);
q[i,3]:=i;
end;
qsort1(1,n); qsort2(1,m);
mx:=0;
fillchar(f,sizeof(f),$7f);
fillchar(g,sizeof(g),$7f);
f[0]:=0;
for i:=1 to m do
begin
while (mx<n)and(a[mx+1,3]<=q[i,1]) do
begin
inc(mx);
for j:=maxn-a[mx,2] downto 0 do
if f[j]<=1000000000 then f[j+a[mx,2]]:=min(f[j+a[mx,2]],f[j]+a[mx,1]);
for j:=maxn downto 0 do
if f[j]<=1000000000 then g[j]:=min(g[j+1],f[j]) else g[j]:=g[j+1];
end;
l:=0;r:=maxn;
while l<r do
begin
mid:=(l+r) div 2;
if g[mid]<=q[i,2] then
begin
ans[q[i,3]]:=mid;l:=mid+1;
end else r:=mid-1;
end;
if g[l]<=q[i,2] then ans[q[i,3]]:=l;
end;
for i:=1 to m do writeln(ans[i]);
end.