题解:P14507 缺零分治 mexdnc
题意简述
有
题目分析
显然
我们先特判掉
考虑其它情况什么时候无解。当
考虑什么时候答案为
考虑一般情况。对于
注意到在上述过程中,每步最多将所有集合的
于是我们就可以愉快地二分了!每次将
时间复杂度
::::success[代码]
#include<bits/stdc++.h>
using namespace std;
long long T,n,q,m,l,r,d,c,z,i,a[100005],b[100005],f[100005],t[100005],p[100005],o[100005];
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>T;
while(T--){
cin>>n>>q;
for(i=0;i<=n;i++)f[i]=0;
for(i=0;i<n;i++){
cin>>a[i]>>b[i];
if(a[i]<=n)f[a[i]]+=b[i];
}
if(!f[0]){
while(q--){
cin>>m;
if(m)cout<<"-1\n";
else cout<<"1\n";
}
continue;
}
for(z=i=1;i<=n;i++)if(f[i]<f[t[z]])t[++z]=i;
for(i=1;z;i++){
a[i]=t[z];
b[i]=f[t[z-1]]-f[t[z]];
p[i]=p[i-1]+a[i]*b[i];
o[i]=o[i-1]+b[i];
c=i;
z--;
}
while(q--){
cin>>m;
if(!m||m>p[c])cout<<"-1\n";
else if(m==p[c])cout<<o[c]<<'\n';
else if(m==a[1])cout<<"1\n";
else if(m<a[1])cout<<"2\n";
else{
l=1;
r=c;
while(l<=r){
d=l+r>>1;
if(p[d]<m)l=d+1;
else r=d-1;
}
cout<<o[r]+(long long)ceil((m-p[r])*1.0/a[r+1])<<'\n';
}
}
}
}
::::