标签:线段树
题意很简单,给出n,m。查询连续m个数的最大值和最小值。
我用线段树 裸的。有人用的单调队列。
不过很忧伤的是G++ TLE,但是C++ AC了。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<bitset> #include<vector> #include<cmath> #define INF 0x7fffffff #define eps 1e-8 #define LL long long #define PI 3.141592654 #define CLR(a,b) memset(a,b,sizeof(a)) #define FOR(i,a,b) for(int i=a;i<b;i++) #define FOR_(i,a,b) for(int i=a;i>=b;i--) #define sf scanf #define pf printf #define all(v) (v).begin(),(v).end() #define acfun std::ios::sync_with_stdio(false) #define SIZE (1000000 +1) #define MOD 1000000007 using namespace std; int arr[SIZE*3]; int _max[SIZE*3]; int _min[SIZE*3]; void build(int l,int r,int o) { if(l==r) { _max[o]=arr[l]; _min[o]=arr[l]; } else { int m=(l+r)>>1;; build(l,m,o*2); build(m+1,r,o*2+1); _max[o]=max(_max[o*2],_max[o*2+1]); _min[o]=min(_min[o*2],_min[o*2+1]); } } int ql,qr; int minans,maxans; void query(int l,int r,int o) { if(ql<=l&&qr>=r) { minans=min(minans,_min[o]); maxans=max(maxans,_max[o]); } else { int m=(l+r)>>1; if(ql<=m)query(l,m,o*2); if(qr>m)query(m+1,r,o*2+1); } } int resmax[SIZE]; int resmin[SIZE]; int main() { int n,m; while(~sf("%d%d",&n,&m)) { FOR(i,1,n+1) sf("%d",&arr[i]); build(1,n,1); FOR(i,1,n-m+2) { minans=INF,maxans=-INF; ql=i,qr=i+m-1; //pf("%d -- %d\n",ql,qr); query(1,n,1); resmax[i]=maxans; resmin[i]=minans; } FOR(i,1,n-m+1) pf("%d ",resmin[i]); pf("%d\n",resmin[n-m+1]); FOR(i,1,n-m+1) pf("%d ",resmax[i]); pf("%d\n",resmax[n-m+1]); } }
标签:线段树
原文地址:http://blog.csdn.net/dongshimou/article/details/43195073