题意,一个有序数组,进行m次查询,每次输出L1-R1,L2-R2两个子序列组成的新序列的中位数
思路:题目可以转化为求新序列中第k个数字为多少,分类讨论,两个子序列可能交叉,可能一个完全包含另一个,也可能完全分离。
这次也调了好久的bug,和以往不同,几乎没有看程序,一直出数据猜。。结果最后发现错误很容易就能看出来,看来调bug时不能一直看程序,也不能一直瞎出数据啊
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 150
#define mod 110119
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
LL a[100005];
LL n,m;
LL L1,R1,L2,R2;
double ans;
LL len1,len2,len;
LL solve(LL k){
// cout<<"k="<<k<<endl;
LL rel;
if(R1<L2){ //不相交
if(k<=len1){
rel=L1-1+k;
}else{
rel=L2-1+k-len1;
}
}else if(R2<=R1){ //完全包含
if(k<=L2-L1+1){
rel=L1-1+k;
}else if(k<=L2-L1+len2*2){
rel=L2-1+(k-(L2-L1)+1)/2;
}else{
rel=L1-1+k-len2;
}
}else if(L2<=R1){
if(k<=L2-L1){
rel=L1-1+k;
}else if(k<=L2-L1+(R1-L2+1)*2){
rel=L2-1+(k-(L2-L1)+1)/2;
}else{
rel=L1-1+k-(R1-L2+1);
}
}
// printf("a[%d]=%d\n",rel,a[rel]);
return a[rel];
}
int main(){
// IN;
int t;
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=0;i<m;i++){
scanf("%lld%lld%lld%lld",&L1,&R1,&L2,&R2);
if(L1>L2){
LL tmp=L1;
L1=L2;L2=tmp;
tmp=R1;R1=R2;R2=tmp;
}
len1=R1-L1+1;
len2=R2-L2+1;
len=len1+len2;
if((len)%2==0){
LL num1=solve(len/2);
LL num2=solve(len/2+1);
ans=(double)(num1+num2)/2;
printf("%.1f\n",ans);
}
else{
ans=(double)solve(len/2+1);
printf("%.1f\n",ans);
}
}
}
}