PTA | 程序设计类实验辅助教学平台 ZOJ3606
枚举每个价格的数量,所以开3颗线段树维护即可
// Problem: G - Lazy Salesgirl
// Contest: Virtual Judge - The 9th Zhejiang Provincial Collegiate Programming Contest
// URL: https://vjudge.net/contest/16323#problem/G
// Memory Limit: 64 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<iomanip>
#define INF (1<<30)
using namespace std;
typedef long long ll;
typedef double d;
const int N=1e5+9;
struct customer{
int p,t;
friend bool operator < (const customer &a,const customer &b){
return a.t<b.t;
}
}c[N];
struct inf{
int id,w;
friend bool operator < (const inf &a,const inf &b){
return a.w<b.w;
}
}pos[N];
int sum[N<<2];
struct node{
d val;
}seg[4][N<<2];
ll tl(ll x){return x<<1;}
ll tr(ll x){return x<<1|1;}
void pushup(int id){
sum[id]=sum[tl(id)]+sum[tr(id)];
for(int i=1;i<=3;i++){
int t=(i+sum[tl(id)]-1)%3+1;
seg[i][id].val=seg[i][tl(id)].val+seg[t][tr(id)].val;
}
}
void update(int id,int l,int r,int pos,ll v){
if(l==r){
sum[id]++;
for(int i=1;i<=3;i++){
seg[i][id].val=i*v;
}
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
update(tl(id),l,mid,pos,v);
}else{
update(tr(id),mid+1,r,pos,v);
}
pushup(id);
}
void solve(){
memset(sum,0,sizeof(sum));
memset(seg,0,sizeof(seg));
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i].p;
}
for(int i=1;i<=n;i++){
cin>>c[i].t;
}
sort(c+1,c+1+n);
pos[1].id=1;
pos[1].w=c[1].t;
for(int i=2;i<=n;i++){
pos[i].id=i;
pos[i].w=(c[i].t-c[i-1].t);
}
sort(pos+1,pos+1+n);
d w=0;
d ans=0;
int j=0;
for(int i=1;i<=n;){
j=i;
while(j<=n && pos[j].w==pos[i].w){
update(1,1,n,pos[j].id,c[pos[j].id].p);
j++;
}
d s=1.0*seg[1][1].val/sum[1];
if(s>ans){
ans=s;
w=pos[i].w;
}
i=j;
}
cout<<fixed<<setprecision(6)<<w<<" "<<ans<<'\n';
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}