小记:求区间最值是可以用树状数组解的,但是这题我交c++最开始9600+ms过了,然后G++过不了,然后就优化,最后C++优化到了5600+ms过了,但是G++还是过不了
这个郁闷啊,一看discuss都是这样, 向来缘浅,奈何情深。 我不想放弃,遂看了一下别人的优化, 一看吓一跳, 优化IO,791ms过了。。。。
然后我改了我的代码的输入,提交c++要7000+ms,提交G++2000+ms过了。
思路:参考这篇:点击
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for( a = b; a < c; ++a)
#define eps 10e-8
#define MAX_ 1000010
int a[MAX_];
int idx[MAX_], idy[MAX_];
int mmx[MAX_], mmi[MAX_];
int n, m;
inline int lowbit(int x){return x&(-x);}
inline int max(int a, int b){
return a<b?b:a;
}
inline int min(int a, int b){
return a<b?a:b;
}
void init(){
int i, j;
for( i = 1; i <= n; ++i){
idx[i] = a[i];
idy[i] = a[i];
for( j = 1; j < lowbit(i); j<<=1){
idx[i] = max(idx[i],idx[i-j]);
idy[i] = min(idy[i],idy[i-j]);
}
}
}
inline int query1(int l,int r){
int ans = a[r];
while(1){
ans = min(a[r], ans);
if(l == r)break;
for(r--; r-l >= lowbit(r); r -= lowbit(r)){
ans = min(ans,idy[r]);
}
}
return ans;
}
inline int query(int l,int r){
int ans = a[r];
while(1){
ans = max(a[r],ans);
if(l == r)break;
for(r--; r-l >= lowbit(r); r -= lowbit(r)){
ans = max(ans,idx[r]);
}
}
return ans;
}
inline void put(int x){
if(x< 0){
putchar('-');
x = -x;
}
if(x == 0){
putchar('0');
return;
}
char s[20];
int bas = 0;
for(;x;x/=10)s[bas++] = x%10+'0';
for(;bas--;)putchar(s[bas]);
return;
}
int main(){
int T, s, t, tmp, i, cnt;
while(~scanf("%d%d", &n, &m)){
REP(i, 1, n+1){
scanf("%d", &a[i]);
}
init();
cnt = query1(1, m);
put(cnt);
REP(i, 2, n+1){
if(i + m - 1<= n){
if(cnt == a[i-1]){
cnt = query1(i, i+m-1);
}else{
cnt = min(cnt, a[i+m-1]);
}
putchar(' ');
put(cnt);
}
else break;
}
cnt = query(1, m);
putchar('\n');
put(cnt);
REP(i, 2, n+1){
if(i + m - 1<= n){
if(cnt == a[i-1]){
cnt = query(i, i+m-1);
}else{
cnt = max(cnt, a[i+m-1]);
}
putchar(' ');
put(cnt);
//printf(" %d", cnt);
}
else break;
}
putchar('\n');
}
return 0;
}