1 /*
2 题意:售货员每隔w分钟就会睡觉,如果售货员睡着了那么顾客会叫醒她但是不会买东西,
3 有n个客人会不同时间来,并且售货员卖给第i的客人的价格为p[i],并且售货员会在第k次卖
4 出1+(k-1)%3个面包,求问最小的w使平均每次卖出的面包的价格最大即总收入/卖的次数;
5
6 分析:如果w小于最小的时间间隔,那么售货员不会卖出一个面包显然不是最优的,
7 当w>某一个时间间隔,那么会买面包的顾客都是时间间隔小于w的,
8 显然最后答案肯定是某一个顾客的时间间隔,枚举要O(n^2),肯定超时;
9 我们知道当w按顾客时间间隔递增,那么前面会买面包的顾客后面还是同样会买的,
10 改变的只是卖的面包的个数,
11
12 现在要完成的工作就是 单点更新,然后按照1,2,3,1,2,3的个数卖,求总收入和总买的次数
13
14 我们可以通过线段树来完成这个工作,
15 定义c[N<<2][3]和pos[N<<2];
16 c[i][0]表示线段i起始位置顾客买1个面包,总的收入;
17 c[i][1]表示线段i起始位置顾客买2个面包,总的收入;
18 c[i][2]表示线段i起始位置顾客买3个面包,总的收入;
19 pos[i]表示线段i里买面包的顾客的人数
20
21 这样就可以通过c[rt<<1][]和c[rt<<1|1][],来递推c[rt][];
22 具体见代码;可以手推枚举一下;
23 trick:读入的时间不是按照顺序来的,要先排序,这个trick虽然很常见
24 但是如果一不小心还是很容易掉进去不能自拔的;
25
26
27 */
28 #include<cstdio>
29 #include<cstring>
30 #include<cstdlib>
31 #include<iostream>
32 #include<algorithm>
33 #include<vector>
34 #include<map>
35 #define lson l,m,rt<<1
36 #define rson m+1,r,rt<<1|1
37 using namespace std;
38 typedef long long LL;
39 const int N=100000+10;
40 const double eps=1e-10;
41 LL c[N<<2][3];
42 int pos[N<<2];
43 vector<int> x,g[N];
44 int n,n1;
45 struct node{
46 int pi,ti;
47 bool operator < (const node&p)const{
48 return ti<p.ti;
49 }
50 }nd[N];
51 void init(){
52 x.clear();
53 for (int i=1;i<=n;i++){
54 scanf("%d",&nd[i].pi);
55 }
56 nd[0].ti=0;
57 for (int i=1;i<=n;i++){
58 scanf("%d",&nd[i].ti);
59 }
60 sort(nd+1,nd+n+1);
61 for (int i=1;i<=n;i++){
62 x.push_back(nd[i].ti-nd[i-1].ti);
63 }
64 sort(x.begin(),x.end());
65 n1=unique(x.begin(),x.end())-x.begin();
66 for (int i=0;i<=n1;i++) g[i].clear();
67 for (int i=1;i<=n;i++){
68 int tmp=lower_bound(x.begin(),x.begin()+n1,nd[i].ti-nd[i-1].ti)-x.begin();
69 g[tmp].push_back(i);
70 }
71 //cout<<"*** "<<endl;
72 //for (int i=0;i<n1;i++) cout<<x[i]<<" ";cout<<endl;
73 }
74 void pushup(int rt){
75 int t;
76 pos[rt]=pos[rt<<1]+pos[rt<<1|1];
77 t=pos[rt<<1]%3;
78 for (int i=0;i<3;i++)
79 c[rt][i]=c[rt<<1][i]+c[rt<<1|1][(t+i)%3];
80
81 }
82 void update(int L,int l,int r,int rt){
83 if (l==r){
84 c[rt][0]=nd[l].pi;
85 c[rt][1]=nd[l].pi*2;
86 c[rt][2]=nd[l].pi*3;
87 pos[rt]=1;
88 return;
89 }
90 int m=(l+r)>>1;
91 if (L<=m) update(L,lson);
92 else update(L,rson);
93 pushup(rt);
94 }
95 void work(){
96 LL ret1=0,ret2=0,ret3;
97 memset(c,0,sizeof(c));
98 memset(pos,0,sizeof(pos));
99 for (int i=0;i<n1;i++){
100 int sz=g[i].size();
101 if (sz!=0){
102 for (int j=0;j<sz;j++){
103 int v=g[i][j];
104 update(v,1,n,1);
105 }
106 //double tmp=(double)c[1][0]/pos[1];
107 // cout<<i<<" ** "<<c[1][0]<<" "<<pos[1]<<endl;
108 if (ret1==0 || c[1][0]*ret2>ret1*pos[1]) {
109 ret1=c[1][0];
110 ret2=pos[1];
111 ret3=x[i];
112 }
113 }
114 }
115 printf("%.6lf %.6lf\n",(double)ret3+eps,(double)ret1/ret2+eps);
116 }
117 int main(){
118 int T;scanf("%d",&T);
119 while (T--){
120 scanf("%d",&n);
121 init();
122 work();
123 }
124 return 0;
125 }