小记:求区间最值是可以用树状数组解的,但是这题我交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; }