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
",1.0*a[an1]);
15     else
16     {
17         if(an1==l2)an2=r1;
18         else an2=an1-1;
19         printf("%.1f
",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
",1.0*a[an1]);
43     else printf("%.1f
",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 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7218690.html