hdu5867 中位数

来源:互联网 发布:匹诺曹软件下载 编辑:程序博客网 时间:2024/06/11 20:47

题意,一个有序数组,进行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);}}}}


0 0