2020牛客多校第二场
场上解决:C,D,F
已补题: A,B,G,H,J,K
All with Pairs
字符串
题意
给你n个字符串,定义
f
(
s
,
t
)
f(s,t)
f(s,t)表示串s的前缀和t的后缀的最长匹配长度求:
∑
i
=
1
n
∑
j
=
1
n
f
(
s
i
,
s
j
)
2
(
m
o
d
998244353
)
\sum_{i=1}^{n}\sum_{j=1}^{n}f(s_i,s_j)^2(mod\ 998244353)
i=1∑nj=1∑nf(si,sj)2(mod 998244353)
解法
hash字符串的后缀,利用map计数,枚举每个字符串的前缀,找到多少个与之匹配的后缀,但对于同一个字符串,倘若前缀a,为前缀b的后缀,应该只计算前缀b,这显然就是
k
m
p
kmp
kmp的next数组。枚举时对每个字符串从前往后枚举
c
n
t
[
i
]
=
m
a
p
[
h
a
s
h
(
p
r
e
(
i
)
)
]
,
c
n
t
[
n
e
x
t
[
i
]
]
−
=
c
n
t
[
i
]
cnt[i] = map[hash(pre(i))],cnt[next[i]]-=cnt[i]
cnt[i]=map[hash(pre(i))],cnt[next[i]]−=cnt[i]
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pi 3.1415926535
using namespace std;
const int mod = 998244353;
ll d[1000005];
string s[100005];
char p[1000005];
int n;
map<ll,ll> num;
int Next[1000005];
ll cnt[1000005];
int b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
d[0] = 1;
b = 113;
for(int i=1;i<1000002;i++){
d[i] = d[i-1]*b;
}
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i];
int len = s[i].length();
ll val = 0;
for(int j = len-1;j>=0;j--){
val+=d[len-j-1]*(s[i][j]-'a'+1);
num[val]++;
}
}
ll ans = 0;
for(int k=0;k<n;k++){
ll val = 0;
int m = s[k].length();
s[k].copy(p+1,m,0),p[m+1] = '\0';
Next[1] = 0;
val = p[1]-'a'+1;
cnt[1] = num[val];
for(int i=2,j=0;i<=m;i++){//求next数组
while(j > 0 && p[i] != p[j+1]) j=Next[j];
if(p[i] == p[j+1]) j++;
Next[i]=j;
val*=b;
val+=p[i]-'a'+1;
cnt[i] = num[val];
if(j) cnt[j] -= cnt[i];
}
for(ll j=1;j<=m;j++){
ans+=1ll*cnt[j]%mod*(j)%mod*(j)%mod;
ans %= mod;
}
}
cout<<ans<<endl;
}
Boundary
计算几何
题意
给你n个点,保证不重复且不在原点,求在所有经过原点的圆中,圆上给定点最多的数目是多少
解法
将每个点与原点相连,得到这条线段的垂直平分线,共有n条,n条垂直平分线两两相交得到可能的圆心,统计一个圆心出现的次数,次数最多的圆心所在圆即答案所在圆,计算这个圆心所在圆上的给定点数目(注意判断共线问题和一个点的情况);
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pll pair<int,int>
#define pi 3.1415926535
using namespace std;
const double eps = 1e-6;
int n,tot;
struct nodi{
int x,y;
}a[2005];
struct nodd{
double x,y;
}b[5000005];
bool cmp(nodd a,nodd b){
if(fabs(a.x - b.x)<eps ) return a.y<b.y;
else return a.x<b.x;
}
int main(){
scanf("%d",&n);
if(n==1){
cout<<1<<endl;
return 0;
}
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
int num = 0;
int ans = 0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
//if(i==j) continue;
if(a[i].x*a[j].y == a[i].y*a[j].x) continue;
// cout<<i<<'*'<<j<<endl;
ans = 1;
int p=i,q=j;
if(a[p].y!=0 && a[q].y!=0){
double c1 = (1.0*a[i].x*a[i].x+1.0*a[i].y*a[i].y)/2.0;
double c2 = (1.0*a[j].x*a[j].x+1.0*a[j].y*a[j].y)/2.0;
double dx = (c1*a[j].y-c2*a[i].y)/(a[i].x*a[j].y-a[j].x*a[i].y);
double dy = (c1*a[j].x-c2*a[i].x)/(a[j].x*a[i].y-a[i].x*a[j].y);
b[tot++] = {dx,dy};
}else{
if(a[p].y==0) swap(p,q);
double dx = 1.0*a[q].x/2.0;
double c = (1.0*a[p].x*a[p].x+1.0*a[p].y*a[p].y)/2.0;
double dy = (c-a[p].x*dx)/(1.0*a[p].y);
b[tot++] = {dx,dy};
}
}
}
sort(b,b+tot,cmp);
for(int i=1;i<tot;i++){
if(fabs(b[i].x-b[i-1].x)<eps && fabs(b[i].y-b[i-1].y)<eps){
if(num==0) num = 1;
num++;
ans = max(ans,num);
}else{
num = 0;
}
}
ans *= 2;
int as = 1;
while(1){
if(as*(as-1)==ans){
printf("%d\n",as);
break;
}
as ++;
}
}
Cover the Tree
贪心,树
题意
给你一颗树,用最少的链覆盖所有的边
解法
答案显然是将叶子两两相连,数目是
⌈
叶
子
数
目
/
2
⌉
\lceil叶子数目/2\rceil
⌈叶子数目/2⌉,考虑如何构造解,
或者可以考虑随机算法,随机若干次直到满足。
Duration
签到题,模拟
题意
给你一天的两个时刻,求相差的秒数
解法
全部化成秒,相减取绝对值
Exclusive OR
FWT
题意
给你n个整数, A 1 , A 2 , . . . , A n A_1,A_2,...,A_n A1,A2,...,An,输出i个数,第i个数为从给你的数中选出i个数的异或值的最大值,可以重复选择
解法
小范围暴力,大范围规律,对于 i > 19 i>19 i>19之后有 a n s i = a n s i − 2 ans_i =ans_{i-2} ansi=ansi−2,因为A< 2 18 2^{18} 218,所以最多第19轮达到满秩,小范围暴力可以依靠异或卷积FWT完成
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
using namespace std;
const int N = (1<<18);
const int MOD = 998244353;
ll qpow(ll a,ll b){
ll res = 1;
while(b){
if(b&1) res = res * a % MOD;
b>>=1;
a = a*a%MOD;
}
return res;
}
int inv2 ;
void FWT_xor(ll *a,int opt)
{
for(int i=1;i<N;i<<=1){
//cout<<'_'<<i<<' '<<N<<endl;
for(int p=i<<1,j=0;j<N;j+=p){
// cout<<'*'<<j<<endl;
for(int k=0;k<i;++k)
{
//cout<<k<<endl;
int X=a[j+k],Y=a[i+j+k];
a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD;
if(opt==-1)a[j+k]=1ll*a[j+k]*inv2%MOD,a[i+j+k]=1ll*a[i+j+k]*inv2%MOD;
}
}
}
}
int n,A;
ll a[N<<1],b[N<<1];
int ans[200005];
int main(){
inv2 = qpow(2,MOD-2);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&A);
a[A] = 1;
b[A] = 1;
ans[1] = max(ans[1],A);
}
FWT_xor(a,1);
for(int i=2;i<=20;i++){
//cout<<i<<endl;
FWT_xor(b,1);
for(int j=0;j<N;j++) b[j] = a[j]*b[j]%MOD;
FWT_xor(b,-1);
// cout<<i<<endl;
for(int j=N-1;j>=0;j--){
if(b[j]){
ans[i] = j;
break;
}
}
}
for(int i=21;i<=n;i++) ans[i] = ans[i-2];
for(int i=1;i<=n;i++){
if(i>1) printf(" ");
printf("%d",ans[i]);
}
}
Fake Maxpooling
签到,模拟,优化
题意
给定一个 n ∗ m n*m n∗m的矩阵,第 ( i , j ) (i,j) (i,j)个位置的值为 l c m ( i , j ) lcm(i,j) lcm(i,j),有一个 k ∗ k k*k k∗k的框在矩阵内移动,求这个框在所有位置的最大值的和
解法
g c d gcd gcd写记忆化,滑动窗口维护最大值
Greater and Greater
b i t s e t bitset bitset 优化
题意
给你一个长度为n的序列A,和一个长度为m的序列B,求有多少长为m的A的子序列S,满足 ∀ i ∈ { 1 , 2 , . . . m } , S i > B i \forall i\in\{1,2,...m\},S_i>B_i ∀i∈{1,2,...m},Si>Bi
解法
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pi 3.1415926535
using namespace std;
int n,m;
int a[150005];
struct nd{
int val,id;
}b[40005];
bitset<40005> s,ss[40005],cur;
int fd(int x){
int l = 0,r = m;
while(l<r){
int mid = (l+r)>>1;
if(b[mid].val> x) r = mid;
else l = mid+1;
}
return l;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&b[i].val);
b[i].id = i;
}
b[m].val = inf;
sort(b,b+m,[](nd x,nd y){return x.val<y.val;});
for(int i=1;i<m;i++){
ss[i] = ss[i-1];
ss[i][b[i-1].id]=1;
}
for(int i=0;i<m;i++) ss[m][i] = 1;
for(int i=0;i<m;i++) cur[i] = 1;
for(int i=0;i<m;i++){
s = ss[fd(a[i])];
cur<<=1;
cur[0] = 1;
cur&=s;
}
int ans = 0;
if(cur[m-1]==1) ans++;
for(int i=m;i<n;i++){
s = ss[fd(a[i])];
cur<<=1;
cur[0] = 1;
cur&=s;
if(cur[m-1] == 1) ans++;
}
printf("%d\n",ans);
return 0;
}
Happy Triangle
数据结构
题意
给你一个multiset,三个操作,操作一为插入一个元素x,操作二为删除一个元素x,操作三位判断multiset中是否有两个数与x构成一个不退化三角形
解法
判断能否构成三角形,有两种情况,一是x为最长边,则存在两条边 a + b > x a+b>x a+b>x使用小于等于x的最大的两条边判断即可,这里可以用set+map维护,set存在集合中的数,map存各个数的数量。
二是x为非最长边,即存在 a − b < x a-b<x a−b<x ,可以使用权值线段树维护,对每个权值,线段树维护集合中他与前一个值的差,若存在多个即为0,没有前置或不在集合中则为INF。
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pi 3.1415926535
using namespace std;
const int INF = 2*inf;
const int maxn = 2e5+5;
struct ask{
int op,x;//,id;
}a[maxn];
int b[maxn],q,m;
set<int> s;
map<int,int> mp;
struct stree{
int l,r;
int val;
}t[maxn<<2];
void pushup(int x){
t[x].val = min(t[x<<1].val,t[x<<1|1].val);
}
void build(int x,int l,int r){
t[x].l = l,t[x].r = r;
if(l == r){
t[x].val = INF;
return;
}
int mid = (t[x].l+t[x].r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void change(int x,int p,int val){
if(t[x].l == t[x].r){
t[x].val = val;
return;
}
int mid = (t[x].l+t[x].r)>>1;
if(p<=mid) change(x<<1,p,val);
else change(x<<1|1,p,val);
pushup(x);
}
int query(int x,int l,int r){
if(t[x].l>=l && t[x].r<=r){
return t[x].val;
}
int mid = (t[x].l+t[x].r)>>1;
int res = INF;
if(mid>=l) res = min(res,query(x<<1,l,r));
if(mid<r) res = min(res,query(x<<1|1,l,r));
return res;
}
int main(){
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d%d",&a[i].op,&a[i].x);
b[i] = a[i].x;
}
sort(b,b+q);
m = unique(b,b+q)-b;
build(1,1,m);
s.insert(-1);
mp[-1] = 1;
int num=0;
for(int i=0;i<q;i++){
int x = a[i].x;
int p = lower_bound(b,b+m,x)-b+1;
if(a[i].op == 1){
num++;
mp[x] ++;
if(mp[x] == 1){
s.insert(x);
auto it = s.find(x);
auto itt = it;
it++;
itt--;
if(*itt == -1){
change(1,p,INF);
}else{
change(1,p,x-*itt);
}
if(it != s.end() && mp[*it]==1){
p = lower_bound(b,b+m,*it)-b+1;
change(1,p,*it-x);
}
}else{
change(1,p,0);
}
}else if(a[i].op == 2){
num--;
mp[x]--;
if(mp[x]==1){
auto it = s.find(x);
it--;
if(*it == -1) change(1,p,INF);
else change(1,p,x-*it);
}else if(mp[x] == 0){
change(1,p,INF);
auto it = s.find(x);
auto itt = it;
it++;
itt--;
if(it!=s.end() && mp[*it]==1){
p = lower_bound(b,b+m,*it)-b+1;
if(*itt == -1) change(1,p,INF);
else change(1,p,*it-*itt);
}
s.erase(x);
}
}else{
if(num<2){
puts("No");
continue;
}
auto it = s.upper_bound(x);
it--;
bool f = 1;
int mx = *it;
if(*it == -1) f = 0;
else{
if(mp[*it]>1){
mx += *it;
}else{
it--;
mx += *it;
if(*it == -1)
f=0;
}
}
if(mx > x && f){
puts("Yes");
}else{
int mn = query(1,p,m);
if(x>mn){
puts("Yes");
}else{
puts("No");
}
}
}
}
}
Interval
网格网络流
题意
给你元组(l,r),可以进行缩减和扩张操作,你可以花一些费用禁止一些操作。求最小的费用使得 l ! = r l!=r l!=r.
解法
裸的网格图网络流,对偶图最短路=最小割
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
using namespace std;
const int N=500010;
vector<int> ver[N],edge[N];
ll d[N];//到起点的距离
bool v[N];
int n,m,s,t;
priority_queue<pair<ll,int> > q;//第一维为-d[x],第二维为x
void dijkstra(){
memset(d,0x3f,sizeof(d));
d[s]=0;
q.push(make_pair(0,s));
// cout<<s<<endl;
while(!q.empty()){
int x=q.top().second;
q.pop();
if(v[x]) continue;
v[x]=1;
int len=ver[x].size();
for(int i=0;i<len;i++){
int y=ver[x][i];
ll z=edge[x][i];
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));
}
}
}
}
void add(int x,int y,ll w){
ver[x].pb(y),ver[y].pb(x);
edge[x].pb(w),edge[y].pb(w);
}
int id[505][505];
int tot;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
for(int j=1;j<n;j++)
id[i][j] = ++tot;
}
s = ++tot;
t = ++tot;
while(m--){
int l,r;
ll c;
char dir;
scanf("%d%d",&l,&r);
getchar();
dir = getchar();
scanf("%lld",&c);
//cout<<dir<<endl;
if(dir=='L'){
if(r==n)
add(id[l][r-1],t,c);
else
add(id[l][r-1],id[l][r],c);
}
else{
if(l==1)
add(id[l][r-1],s,c);
else
add(id[l][r-1],id[l-1][r-1],c);
}
}
// cout<<"***"<<endl;
dijkstra();
// cout<<"___"<<endl;
if(d[t] >= d[N-1]){
puts("-1");
}else{
printf("%lld\n",d[t]);
}
}
Just Shuffle
数学
题意
给定一个 1 1 1~ n n n的排列A,求一个置换B,使得 1 , 2 , 3... n {1,2,3...n} 1,2,3...n经过k轮置换变成A
解法
对每个环,长度为r,即周期为r,假设{ a 1 , a 2 . . . , a r a_1,a_2...,a_r a1,a2...,ar}( a 1 < a 2 < . . . < a r a_1<a_2<...<a_r a1<a2<...<ar)表示为 A m A^m Am, 故 ( A m ) k = A k m = A (A^m)^k = A^{km} = A (Am)k=Akm=A,即 k m % r = 1 km\%r=1 km%r=1 故 m为模r意义下 k − 1 k^{-1} k−1,答案为 A m + 1 A^{m+1} Am+1
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pi 3.1415926535
using namespace std;
const int N = 1e5+5;
int a[N],used[N],ans[N],tmp[N];
vector<int> seq;
int n,m;
ll ex_gcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
else {
ll r = ex_gcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
}
ll inv(ll a, ll p) {//a在模p意义下的逆元若gcd(a,p)!=1,逆元不存在
ll x, y;
ex_gcd(a, p, x, y);
x = (x % p + p) % p;
return x;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
if(!used[i]){//若之前已经出现在某个环上不操作
seq.clear();
int now = i;
//找环
while(!used[now]){
seq.pb(now);
used[now] = 1;
now = a[now];
}
int k = inv(m%seq.size(),seq.size());
for(int j=0;j<seq.size();j++)
tmp[j] = seq[(j+k)%seq.size()];
for(int j=0;j<seq.size();j++)
ans[seq[j]] = tmp[j];
}
}
for(int i=1;i<=n;i++){
if(i>1) printf(" ");
printf("%d",ans[i]);
}
return 0;
}
Keyboard Free
期望,积分,计算几何
题意
给你三个同心圆,从各圆中任取一点,求这三个点构成三角形面积的期望
解法
固定A点,枚举B点。AB都固定的情况下显然可以积分算出ABC三角形以AB为底的高的期望
对于一个固定的 AB,我们可以求出线段长度 L 以及它与圆心的距离 H 和夹角 α ,显然有
a
l
p
h
a
<
π
2
alpha < \frac{\pi}{2}
alpha<2π
接着通过积分求出 C 点运动时这个三角形的期望高,我们将其分成三部分。
s
u
m
1
=
∫
0
π
(
H
+
r
3
×
s
i
n
(
x
)
)
d
x
=
π
H
+
r
3
×
∫
0
π
s
i
n
(
x
)
d
x
=
π
H
+
2
×
r
3
sum_1=\int_{0}^{\pi}(H+r3\times sin(x))dx=\pi H + r3\times \int_{0}^{\pi}sin(x)dx=\pi H+2\times r3
sum1=∫0π(H+r3×sin(x))dx=πH+r3×∫0πsin(x)dx=πH+2×r3
s u m 2 = 2 ∫ 0 α ( H − r 3 × s i n ( x ) ) d x = 2 ( H α − r 3 ∫ 0 α s i n ( x ) d x ) = 2 ( α H + r 3 × c o s ( α ) − r 3 ) sum_2=2\int_{0}^{\alpha}(H-r3\times sin(x))dx=2(H\alpha - r3\int_{0}^{\alpha}sin(x)dx)=2(\alpha H +r3\times cos(\alpha)-r3) sum2=2∫0α(H−r3×sin(x))dx=2(Hα−r3∫0αsin(x)dx)=2(αH+r3×cos(α)−r3)
s u m 3 = ∫ α π − α ( r 3 × s i n ( x ) − H ) d x = r 3 ∫ α π − α s i n ( x ) d x − ( π − 2 α ) H = 2 r 3 × c o s ( α ) − ( π − 2 α ) H sum_3=\int_{\alpha}^{\pi-\alpha}(r3\times sin(x)-H)dx=r3\int_{\alpha}^{\pi-\alpha}sin(x)dx-(\pi-2\alpha)H=2r3\times cos(\alpha)-(\pi-2\alpha)H sum3=∫απ−α(r3×sin(x)−H)dx=r3∫απ−αsin(x)dx−(π−2α)H=2r3×cos(α)−(π−2α)H
故
s
u
m
=
π
H
+
2
×
r
3
+
2
(
α
H
+
r
3
×
c
o
s
(
α
)
−
r
3
)
+
2
r
3
×
c
o
s
(
α
)
−
(
π
−
2
α
)
H
=
4
r
3
×
c
o
s
(
α
)
+
4
α
×
H
sum=\pi H+2\times r3+2(\alpha H +r3\times cos(\alpha)-r3)+2r3\times cos(\alpha)-(\pi-2\alpha)H=4r3\times cos(\alpha)+4\alpha\times H
sum=πH+2×r3+2(αH+r3×cos(α)−r3)+2r3×cos(α)−(π−2α)H=4r3×cos(α)+4α×H
所以期望高度
h
=
4
r
3
×
c
o
s
(
α
)
+
4
α
×
H
2
π
h=\frac{4r3\times cos(\alpha)+4\alpha\times H}{2\pi}
h=2π4r3×cos(α)+4α×H,期望面积为
h
×
L
2
\frac{h\times L}{2}
2h×L
在圆周上均匀取1000个B点即可
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define inf 0x3f3f3f3f
#define endl "\n"
#define MP(x,y) (make_pair(x,y))
#define pii pair<int,int>
#define pll pair<long long,long long>
using namespace std;
const double pi = acos(-1.0);
int t;
int r1,r2,r3;
double f(double x){
return x*x;
}
void gao(){
scanf("%d%d%d",&r1,&r2,&r3);
if (r1 > r2) swap(r1, r2);
if (r1 > r2) swap(r1, r3);
if (r2 > r3) swap(r2, r3);
double ans = 0;
for(int i=1;i<=1000;i++){
double sina = sin(2.0 * pi / 1000.0 * i);
double cosa = cos(2.0 * pi / 1000.0 * i);
double x = r2*cosa,y = r2*sina;
double l = sqrt(f(x-r1)+f(y));
double h = y/l*r1;
double alpha = asin(h/r3);
double H = (4.0*r3*cos(alpha) + 4.0*alpha*h)/(2.0*pi);
ans += H*l/2;
}
ans /= 1000.0;
printf("%.1f\n",ans);
}
int main(){
scanf("%d",&t);
while(t--){
gao();
}
}