知道题意以后离线来做
两个树状数组 一个存高度 一个存个数
那么你二分的是mid
你就要MID = ceil(向上取整)mid, 答案为高度超过这个MID的和 减去有多少个高度超过MID的竹子个数*mid 进行二分check 一开始ans没有 = 0.0 一直WA
后来才知道二分有问题 好在队友的帮助下 解决了此题
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
//#include <random>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
//#pragma comment(linker,"/STACK:10240000,10240000")
//mt19937 rand_(time(0));
const db EPS = 1e-8;
inline int sign(db a){
return a< -EPS ? -1 : a > EPS;
}
inline int cmp(db a,db b){
return sign(a-b);
}
const int MAX_N = 200025;
double ANS[MAX_N];
int block;
int n,m,arr[MAX_N];
namespace bit
{
long long C[MAX_N<<1];
long long C_[MAX_N<<1];
void add(int x,int v)
{
for(;x<MAX_N;x+=x&(-x))
C[x]+=1LL*v;
}
long long get(int x)
{
ll res = 0;
for(;x;x-=x&(-x))
res+=1LL*C[x];
return res;
}
void ADD(int x,int v)
{
for(;x<MAX_N;x+=x&(-x))
C_[x]+=1LL*v;
}
long long GET(int x)
{
ll res = 0;
for(;x;x-=x&(-x))
res+=1LL*C_[x];
return res;
}
}
struct node {
int l,r,id;
double x,y;
}q[MAX_N];
bool CMP(node a,node b)
{
return (a.l/block)^(b.l/block)?a.l<b.l:(((a.l/block)&1)?a.r<b.r:a.r>b.r);
}
void add(int x){
bit::add(arr[x],arr[x]);
bit::ADD(arr[x],1);
}
void del(int x){
bit::add(arr[x],-arr[x]);
bit::ADD(arr[x],-1);
}
int main(){
//freopen("1.txt","r",stdin);
//ios::sync_with_stdio(false);
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;++i) scanf("%d",&arr[i]);
block = n/sqrt(m*2/3);
for(int i = 1;i<=m;++i)
{
scanf("%d%d%lf%lf",&q[i].l,&q[i].r,&q[i].x,&q[i].y);
q[i].id = i;
}
sort(q+1,q+m+1,CMP);
int L=1,R=0;
for(int i=1;i<=m;++i){
int ql=q[i].l,qr=q[i].r;
int qx = q[i].x;double qy = q[i].y;
while(R<qr)add(++R);
while(L>ql)add(--L);
while(L<ql)del(L++);
while(R>qr)del(R--);
double right = 1.0*bit::get(100005)/qy*qx;
double l = 0.0,r = 100000.0;
double ans =0.0;
while(l<=r)
{
double mid = 1.0*(l+r)/2;
int MID = ceil(mid+EPS);
double left =1.0*bit::get(100005)-bit::get(MID-1)-1.0*(bit::GET(100005)-bit::GET(MID-1))*mid;
if(cmp(left,right)>=0) {ans = mid;l = mid + EPS;}
else r= mid - EPS;
}
ANS[q[i].id] = r;
}
for(int i = 1;i<=m;++i) printf("%.15f\n",ANS[i]);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}