链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5857
题意:求有序序列中[l1,r1],[l2,r2]两端区间的中间数
题解:由于是有序序列且数组较大,直接针对两段区间的所有相交情况进行判断处理对中间数定位就好。
CODE:
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1)
#define eps 1e-5
const int MAXN = 1e5+7;
long long a[MAXN];
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; ++i)
scanf("%I64d",&a[i]);
int l1,r1,l2,r2,len1,len2,mid,all,poi;
long long p1,p2;
double ans;
for(int i=0; i<m; ++i)
{
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
l1--,l2--,r1--,r2--;
if(l1>l2)
{
swap(l1,l2);
swap(r1,r2);
}
len1=r1-l1+1;
len2=r2-l2+1;
all=len1+len2;
mid=all/2+1;
if(r1<l2)//不相交
{
if(all&1)
{
if(l1+mid-1>r1)ans=a[l2+mid-len1-1];
else ans=a[l1+mid-1];
}
else
{
poi=mid-1;
if(l1+mid-1>r1)p1=a[l2+mid-len1-1];
else p1=a[l1+mid-1];
if(l1+poi-1>r1)p2=a[l2+poi-len1-1];
else p2=a[l1+poi-1];
ans=(p1+p2)*1.0/2.0;
}
}
else//相交
{
if(r1<r2)//不包括
{
poi=mid-(l2-l1);
if(poi<=0)
ans=a[l1+mid-1];
else
{
int f=(r1-l2+1)<<1;
if(f+l2-l1>=mid)
ans=a[ l2+(poi-1)/2 ];
else
ans=a[l1+mid-1-(r1-l2+1)];
}
}
else //包括
{
poi=mid-(l2-l1);
if(poi<=0)
ans=a[l1+mid-1];
else
{
int f=(r2-l2+1)<<1;
if(f+l2-l1>=mid)
ans=a[ l2+(poi-1)/2 ];
else
ans=a[l1+mid-1-(r2-l2+1)];
}
}
if(!(all&1))
{
mid--;
if(r1<r2)//不包括
{
poi=mid-(l2-l1);
if(poi<=0)
p1=a[l1+mid-1];
else
{
int f=(r1-l2+1)<<1;
if(f+l2-l1>=mid)
p1=a[ l2+(poi-1)/2 ];
else
p1=a[l1+mid-1-(r1-l2+1)];
}
}
else //包括
{
poi=mid-(l2-l1);
if(poi<=0)
p1=a[l1+mid-1];
else
{
int f=(r2-l2+1)<<1;
if(f+l2-l1>=mid)
p1=a[ l2+(poi-1)/2 ];
else
p1=a[l1+mid-1-(r2-l2+1)];
}
}
ans=(ans+p1)*1.0/2.0;
}
}
printf("%.1f\n",ans);
}
}
return 0;
}