1 条题解
-
0Guest LV 0 MOD
-
1
二分答案,再用树状数组加二分(只是我不会lowerbound就只能手写一个find函数)维护前缀和。
#include<bits/stdc++.h>
const int maxn=100001;
inline const void read(int &a)
{
a=0;char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')
{
a=(a<<1)+(a<<3)+c-'0';
c=getchar();
}
}
inline const void write(int a)
{
if(a<0){a=-a;putchar('-');}
if(a>9)write(a/10);
putchar('0'+a%10);
}
inline const double max(double a,double b)
{
if(a>b)return a;
return b;
}
inline const double min(double a,double b)
{
if(a<b)return a;
return b;
}
inline const int lowbit(int a)
{
return a&(-a);
}
int n,k,sum[maxn];
inline const void modify(int a,int b)
{
a=a+1;
while(a<=n)
{
sum[a]+=b;
a+=lowbit(a);
}
}
inline const int query(int a)
{
a=a+1;
int ans=0;
while(a)
{
ans+=sum[a];
a-=lowbit(a);
}
return ans;
}
double hash[maxn],num[maxn],size[maxn],beauty[maxn];
int order[maxn];
inline const bool comp(double a,double b)
{
if(a<b)return true;
return false;
}
inline const int find(double a)
{
int l=1,r=n;
while(l!=r)
{
int mid=(l+r)>>1;
if(hash[mid]<a)l=mid+1;
else r=mid;
}
while(l-1&&hash[l-1]==a)--l;
return l;
}
inline const int solve(double mid)
{
memset(sum,0,sizeof(sum));
int ans=0;
num[0]=0;
for(int i=1;i<=n;i++)num[i]=hash[i]=num[i-1]+size[i]-mid*beauty[i];
std::sort(hash+1,hash+1+n,comp);
for(int i=1;i<=n;i++)
{
order[i]=find(num[i]);
ans+=query(order[i]);
if(num[i]>=0)ans++;
modify(order[i],1);
}
return ans;
}
int main()
{
double l=100000.0,r=-1.0;
read(n);read(k);
int t;
for(int i=1;i<=n;i++){read(t);size[i]=double(t);}
for(int i=1;i<=n;i++){read(t);beauty[i]=double(t);r=max(r,size[i]/beauty[i]);l=min(l,size[i]/beauty[i]);}
while(r-l>=1e-3)
{
double mid=(r+l)/2;
if(solve(mid)>=k)l=mid;
else r=mid;
}
printf("%.2lf",(l+r)/2);
return 0;
}
- 1
信息
- 难度
- 9
- 分类
- (无)
- 标签
- (无)
- 递交数
- 15
- 已通过
- 3
- 通过率
- 20%
- 上传者