T is about 200.
For 90% of the data, n, m <= 100
For 10% of the data, n, m <= 100000
A[i] fits signed 32-bits int.
1 4 2 1 2 3 4 1 2 2 4 1 1 2 2
2.0 1.5
题意:从一个给定的序列中选取从l1到r1的子序列和从l2到r2的子序列,然后这两个序列融合成一个新的序列,求这个序列的中位数。
思路: 如果l1>l2,那么交换l1与l2,交换r1与r2。然后分类讨论。设新序列的总长为len = r2 - l2 + 1 + r1 - l1 + 1。
那么l1,r1,l2,r2的分布情况如下:
1: l1,r1,l2,r2, 这种情况即两个序列没有交集,可以直接算,挺简单;
2: l1,l2,r1,r2, 这种情况两个序列有交集,交集中的每个元素都按两个算,这个在代码有所体现;
3: l1,l2,r2,r1, 处理情况类似情况二。
然后就是处理中位数,分len的奇数偶数;无论奇数偶数,都需要求len/2 + 1,所以现在就需要偷个懒,嘿嘿,详见代码。
心态:最近心态炸了,似乎只有自己尽力(无奈),省赛选拔队伍一直倒数,不知怎么了,唉,还是保持一颗平常心。
详见代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int op[100010];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d %d",&m,&n);
for(int i=0;i<m;i++)
scanf("%d",&op[i]);
int a,b,aa,bb;
double sum;
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a,&b,&aa,&bb);
aa--;bb--;a--;b--;//预处理序号,从零号开始存储,方便以后
sum = 0;
if(a>aa)swap(a,aa),swap(b,bb); //预处理
int len = b-a + bb-aa + 2;
int p = len/2+1;
if(b<aa){
if(p>b-a+1)
{
sum = op[p-(b-a+1)+aa-1];
}
else
{
sum = op[p+a-1];
} }
else if(b>=aa&&b<=bb)
{
if(p<=aa-a)
{
sum = op[p+a-1];
}else if(p>aa-a&&p<len-(bb-b))
{
int t = p - (aa-a);
if(t%2==0)sum = op[aa-1+t/2];
else sum = op[aa-1+t/2+1];
}
else
{
int t = aa-a + (b-aa+1)*2;
sum = op[p-t+b];
}
}else if(b>bb)
{
if(p<=aa-a)
{
sum = op[p+a-1];
}
else if(p>aa-a&&p<len-(b-bb))
{
int t = p - (aa-a);
if(t%2==0)sum = op[aa-1+t/2];
else sum = op[aa-1+t/2+1];
}else
{
int t = aa-a + (bb-aa+1)*2;
sum = op[p-t+bb+1-1];
}
}
double yy = sum; //方便处理偶数。
if(len%2==1)
printf("%.1lf\n",sum);//这里就是在偷懒了,尽管如此代码还是这么长,智商着急
else
{
p = len / 2;//因为len是偶数,所以求其中位数需要求op[len/2]和op[len/2+1],借用求奇数的。
if(b<aa){
if(p>b-a+1)
{
sum = op[p-(b-a+1)+aa-1];
}
else
{
sum = op[p+a-1];
} }
else if(b>=aa&&b<=bb)
{
if(p<=aa-a)
{
sum = op[p+a-1];
}else if(p>aa-a&&p<len-(bb-b))
{
int t = p - (aa-a);
if(t%2==0)sum = op[aa-1+t/2];
else sum = op[aa-1+t/2+1];
}
else
{
int t = aa-a + (b-aa+1)*2;
sum = op[p-t+b];
}
}else if(b>bb)
{
if(p<=aa-a)
{
sum = op[p+a-1];
}
else if(p>aa-a&&p<len-(b-bb))
{
int t = p - (aa-a);
if(t%2==0)sum = op[aa-1+t/2];
else sum = op[aa-1+t/2+1];
}else
{
int t = aa-a + (bb-aa+1)*2;
sum = op[p-t+bb+1-1];
}
}
printf("%.1lf\n",(yy+sum)/2);
}
}
}
return 0;
}
水波。