hdu 5857 Median(模拟)
题目链接:hdu 5857 Median
题意:
给你n个排好序的数,有m个询问,每次询问给出两个区间,然后让这两个区间的数重新组成一个序列,
然后让你输出这个序列的中位数。
题解:
分类讨论一下。
如果两个区间不重合,那么很直接的就能算出来中位数的位置。
如果重合,就将重合的那一部分数记为占了两个位置。
然后模拟找一下中位数就行了。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 using namespace std; 4 5 const int N=1e5+7; 6 int t,n,m,a[N],l1,l2,r1,r2; 7 8 void work1() 9 { 10 int sum=r1-l1+1+r2-l2+1; 11 int now=sum/2+1,an1,an2; 12 if(now<=r1-l1+1)an1=l1+now-1; 13 else now-=r1-l1+1,an1=l2+now-1; 14 if(sum&1)printf("%.1f\n",1.0*a[an1]); 15 else 16 { 17 if(an1==l2)an2=r1; 18 else an2=an1-1; 19 printf("%.1f\n",0.5*(1ll*a[an1]+a[an2])); 20 } 21 } 22 23 void work2() 24 { 25 int tp[4],sum=r1-l1+1+r2-l2+1; 26 tp[0]=l1,tp[1]=r1,tp[2]=l2,tp[3]=r2; 27 sort(tp,tp+4); 28 int now=sum/2+1,an1,an2; 29 if(now<=tp[1]-tp[0])an1=tp[0]+now-1,an2=an1-1; 30 else if(now<=tp[1]-tp[0]+(tp[2]-tp[1]+1)*2) 31 { 32 int tmp=tp[1]-tp[0]; 33 an1=(now-tmp+1)/2+tp[1]-1; 34 if((now-tmp)&1)an2=an1-1; 35 else an2=an1; 36 }else 37 { 38 int tmp=tp[1]-tp[0]+(tp[2]-tp[1]+1)*2; 39 an1=tp[2]+now-tmp; 40 an2=an1-1; 41 } 42 if(sum&1)printf("%.1f\n",1.0*a[an1]); 43 else printf("%.1f\n",0.5*(1ll*a[an1]+a[an2])); 44 } 45 46 int main(){ 47 scanf("%d",&t); 48 while(t--) 49 { 50 scanf("%d%d",&n,&m); 51 F(i,1,n)scanf("%d",a+i); 52 F(i,1,m) 53 { 54 scanf("%d%d%d%d",&l1,&r1,&l2,&r2); 55 if(r2<=l1)swap(l1,l2),swap(r1,r2); 56 if(r1<l2)work1();else work2(); 57 } 58 } 59 return 0; 60 }