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; }
看题解正解竟然是主席树,先放一下吧。