Description
给出一个长度为n的有序序列Ai,m次查询,每次查询输入两个区间[l1,r1],[l2,r2],输出将这两个区间的数放在一起后的中位数
Input
第一行一整数T表示用例组数,每组用例首先输入两整数n和m表示序列长度和查询数,之后n个整数Ai表示该序列,之后每次输入四个整数l1,r1,l2,r2表示一次查询
(T<=200,n,m<=100000,Ai最多是32位int,l1<=r1,l2<=r2)
Output
对于每次查询,输出将两个区间中数放在一起后的中位数
Sample Input
1
4 2
1 2 3 4
1 2
2 4
1 1
2 2
Sample Output
2.0
1.5
如果重叠,划分成3 个区间,
l1->l2-1,l2->r1,r1+1->r2
或者
l2->l1-1,l1->r2,r2+1->r1
分别对应
a1 a2 a3 a4 a5 a6
如果是奇数
if(a2-a1+1<=x/2)
if(a2-a1+1+(a4-a3+1)*2<=x/2)
mid=c[a6-(x/2)]
else
mid=c[a4-(x/2-(a6-a5+1))/2]
else
mid=c[a1+x/2];
如果是偶数,找x/2+1=mid2;x/2=mid1
if(a2-a1+1<=x/2-1)
if(a2-a1+1+(a4-a3+1)*2<=x/2-1)
mid1=c[a6-(x/2)];
else
mid1=c[a4-(x/2-(a6-a5+1))/2];
else
mid1=c[a1+x/2-1];
if(a2-a1+1<=x/2)
if(a2-a1+1+(a4-a3+1)*2<=x/2)
mid2=c[a6-(x/2-1)];
else
mid2=c[a4-(x/2-1-(a6-a5+1))/2];
else
mid2=c[a1+x/2];
不重叠
如果是奇数
if(r1-l1+1<=x/2)
mid=c[r2-x/2];
else
mid=c[l1+x/2];
如果是偶数mid1,mid2
if(r1-l1+1<=x/2-1)
mid1=c[r2-x/2];
else
mid1=c[l1+x/2-1];
if(r1-l1+1<=x/2)
mid2=c[r2-x/2+1];
else
mid2=c[l1+x/2;]
不能写memset,会超时,,,,,一直超时!
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 100000
int c[maxn+10];
int b[maxn+10];
int d[10];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d %d",&n,&m);
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
while(m--)
{
//memset(b,0,sizeof(b));
int l1,r1,l2,r2;
double mid;
scanf("%d %d",&l1,&r1);
scanf("%d %d",&l2,&r2);
int x=r1-l1+r2-l2+2;
if(r2<l1||r1<l2)
{
int a1,a2,a3,a4;
if(r2<l1)
{
a1=l2;a2=r2;a3=l1;a4=r1;
l1=a1;r1=a2;l2=a3;r2=a4;
}
if(x%2==1)
{
if(r1-l1+1<=x/2)
mid=(double)c[r2-x/2];
else
mid=(double)c[l1+x/2];
}
else
{
int mid1,mid2;
if(r1-l1+1<=x/2-1)
mid1=c[r2-x/2];
else
mid1=c[l1+x/2-1];
if(r1-l1+1<=x/2)
mid2=c[r2-x/2+1];
else
mid2=c[l1+x/2];
mid=((double)mid1+(double)mid2)/2;
}
}
else
{
d[0]=l1;d[1]=r1;d[2]=l2;d[3]=r2;
sort(d,d+4);
l1=d[0];r1=d[2];l2=d[1];r2=d[3];
int a1=l1,a2=l2-1,a3=l2,a4=r1,a5=r1+1,a6=r2;
if(x%2==1)
{
if(a2-a1+1<=x/2)
if(a2-a1+1+(a4-a3+1)*2<=x/2)
mid=(double)c[a6-(x/2)];
else
mid=(double)c[a4-(x/2-(a6-a5+1))/2];
else
mid=(double)c[a1+x/2];
}
else
{
int mid1,mid2;
if(a2-a1+1<=x/2-1)
if(a2-a1+1+(a4-a3+1)*2<=x/2-1)
mid1=c[a6-(x/2)];
else
mid1=c[a4-(x/2-(a6-a5+1))/2];
else
mid1=c[a1+x/2-1];
if(a2-a1+1<=x/2)
if(a2-a1+1+(a4-a3+1)*2<=x/2)
mid2=c[a6-(x/2-1)];
else
mid2=c[a4-(x/2-1-(a6-a5+1))/2];
else
mid2=c[a1+x/2];
mid=((double)mid1+(double)mid2)/2;
}
}
printf("%.1lf\n",mid);
}
}
return 0;
}
//ff