这题我想了一周……然后今天我发现,我,T,M,看,错,题,啦!!!
日了狗
算出每个瓶子被喝多少次之后会喝不了
然后把瓶子按这个排序
然后枚举第几次飞,看当前瓶子是不是在当前这一次被喝没,拿个线段树记录一下区间和乱搞就行了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
ll n,m,d;
ll h[MAXN],a[MAXN],p[MAXN];
ll s[MAXN<<2];
ll S;
bool cmp(ll x,ll y){
return a[x]!=a[y]?a[x]<a[y]:x<y;
}
inline void ud(ll x){
s[x]=s[x<<1]+s[x<<1|1];
}
void build(ll x,ll y,ll z){
if(y==z){
s[x]=1;
return ;
}
ll mid=y+z>>1;
build(x<<1,y,mid);
build(x<<1|1,mid+1,z);
ud(x);
}
void change(ll x,ll y,ll z,ll p,ll cv){
if(y==z){
s[x]=cv;
return ;
}
ll mid=y+z>>1;
if(p<=mid){
change(x<<1,y,mid,p,cv);
}else{
change(x<<1|1,mid+1,z,p,cv);
}
ud(x);
}
ll find(ll x,ll y,ll z,ll av){
if(y==z){
return y;
}
ll mid=y+z>>1;
if(s[x<<1]>=av){
return find(x<<1,y,mid,av);
}else{
return find(x<<1|1,mid+1,z,av-s[x<<1]);
}
}
ll ask(ll x,ll y,ll z,ll l,ll r,ll av){
if(y==l&&z==r){
if(s[x]<av){
return -s[x];
}
return find(x,y,z,av);
}
ll mid=y+z>>1;
if(r<=mid){
return ask(x<<1,y,mid,l,r,av);
}else if(l>mid){
return ask(x<<1|1,mid+1,z,l,r,av);
}else{
ll t=ask(x<<1,y,mid,l,mid,av);
if(t>0){
return t;
}
ll t2=ask(x<<1|1,mid+1,z,mid+1,r,av+t);
if(t2>0){
return t2;
}
return t+t2;
}
}
ll sum(ll x,ll y,ll z,ll l,ll r){
if(y==l&&z==r){
return s[x];
}
ll mid=y+z>>1;
if(r<=mid){
return sum(x<<1,y,mid,l,r);
}else if(l>mid){
return sum(x<<1|1,mid+1,z,l,r);
}else{
return sum(x<<1,y,mid,l,mid)+sum(x<<1|1,mid+1,z,mid+1,r);
}
}
int main(){
/*
freopen("data.txt","r",stdin);
freopen("dui.txt","w",stdout);
//*/
ll i,x;
scanf("%lld%lld%lld",&n,&m,&d);
for(i=1;i<=n;i++){
scanf("%lld",&h[i]);
}
for(i=1;i<=n;i++){
p[i]=i;
scanf("%lld",&x);
if(h[i]<=d){
a[i]=int(floor(1.0*(d-h[i])/x)+1);
}
}
sort(p+1,p+n+1,cmp);
S=n;
ll ed=0;
ll wzh=1;
build(1,1,n);
for(i=1;i<=m;i++){
x=0;
while(wzh<=n){
if(!(a[p[wzh]]-ed)){
change(1,1,n,p[wzh],0);
wzh++;
continue ;
}
if(x==n){
break;
}
int t=ask(1,1,n,x+1,n,a[p[wzh]]-ed);
if(t<=0){
break;
}
change(1,1,n,p[wzh],0);
x=t;
ed=a[p[wzh]];
wzh++;
}
if(x!=n){
ed+=sum(1,1,n,x+1,n);
}
}
printf("%lld\n",ed);
return 0;
}
/*
5 5 30
26 5 15 14 9
5 2 2 5 3
*/