codevs 2021 中庸之道
题目描述 Description
给定一个长度为N的序列,有Q次询问,每次询问区间[L,R]的中位数。
数据保证序列中任意两个数不相同,且询问的所有区间长度为奇数。
输入描述 Input Description
第一行为N,Q。
第二行N个数表示序列。
接下来Q行,每行为L,R,表示一次询问。
输出描述 Output Description
输出Q行,对应每次询问的中位数。
样例输入 Sample Input
5 3
1 4 8 16 2
1 5
3 5
3 3
样例输出 Sample Output
4
8
8
数据范围及提示 Data Size & Hint
40%的数据,N,Q≤100;
70%的数据,N≤100;
100%的数据,N≤1000,Q≤100000,序列中的元素为1到10^9之间的整数。
由于思路的错误,下面这份代码的正确性根本不存在,然而是能够过样例(!!)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1010;
int a[N], middle [N] [N];
int n,Q;
inline int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9')c = getchar();
while(c >= '0' && c <= '9')x = x * 10 + c - '0',c=getchar();
return x;
}
inline int imp (int x)
{
if((a[x] > a[x + 1] && a[x] < a[x + 2]) || (a[x] > a[x + 2] && a[x] < a[x + 1]))return a[x];
if((a[x] < a[x + 1] && a[x + 1] < a[x + 2]) || (a[x] > a[x + 1] && a[x + 1] > a[x + 2]))return a[x + 1];
else return a[x + 2];
}
int _see;
int main()
{
n = read(),Q = read();
for(int i = 1; i <= n; i ++)
a[i] = read(), middle [i] [i] = a[i];
for(int i = 1; i < n; i ++)
{
middle[i] [i + 2] = imp(i);
_see=middle [i] [ i + 2 ];
}
for(int i = 1; i <= n; i ++)
for(int j = i + 4; j <= n; j += 2)
{
int mid = middle [i] [j - 2];
if(a[j] < mid && a[j - 1] < mid)middle [i] [j] = max(a[j],a[j - 1]);
if(a[j] > mid && a[j - 1] > mid)middle [i] [j] = min(a[j],a[j - 1]);
else middle [i] [j] = mid;
_see=middle [i] [j];
}
while( Q -- )
{
int l = read(), r = read();
printf("\n--%d--\n\n", middle [l] [r]);
}
return 0;
}
/*
10 10
4 2 6 3 9 8 7 5 10 1
10 10
3 9
6 10
8 10
2 4
10 10
7 9
3 9
5 7
1 9
*/
sort TLE两个点:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10010;
int a[maxn],d[maxn];
int n,m,b,c;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=n;i++) d[i]=a[i];
for(int i=1;i<=m;i++)
{
scanf("%d%d",&b,&c);
sort(a+b,a+c+1);
printf("%d\n",a[b+c>>1]);
for(int i=1;i<=n;i++) a[i]=d[i];
}
return 0;
}
看题解正解竟然是主席树,先放一下吧。

浙公网安备 33010602011771号