POJ-2823-Sliding Window
http://poj.org/problem?id=2823
求区间的最大值与最小值,线段树即可,C++过了,G++超时,囧
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> using namespace std; #define N 1000005 struct cam { int x; int y; int min; int max; }list[N*4]; int Min(int x,int y) { return x<y?x:y; } int Max(int x,int y) { return x>y?x:y; } void build(int k,int x,int y) { int num,mid; list[k].x=x; list[k].y=y; if(x==y) { scanf("%d",&num); list[k].min=num; list[k].max=num; return; } mid=(x+y)/2; build(k<<1,x,mid); build(k<<1|1,mid+1,y); list[k].min=Min(list[k<<1].min,list[k<<1|1].min); list[k].max=Max(list[k<<1].max,list[k<<1|1].max); } int findmin(int k,int x,int y) { int mid; if(list[k].x==x&&list[k].y==y) return list[k].min; mid=(list[k].x+list[k].y)/2; if(x>mid) return findmin(k<<1|1,x,y); else if(y<=mid) return findmin(k<<1,x,y); else return Min(findmin(k<<1,x,mid),findmin(k<<1|1,mid+1,y)); } int findmax(int k,int x,int y) { int mid; if(list[k].x==x&&list[k].y==y) return list[k].max; mid=(list[k].x+list[k].y)/2; if(x>mid) return findmax(k<<1|1,x,y); else if(y<=mid) return findmax(k<<1,x,y); else return Max(findmax(k<<1,x,mid),findmax(k<<1|1,mid+1,y)); } int main() { int n,k,i; while(scanf("%d%d",&n,&k)!=EOF) { build(1,1,n); for(i=1;i<=n-k+1;i++) { if(i==n-k+1) printf("%d\n",findmin(1,i,i+k-1)); else printf("%d ",findmin(1,i,i+k-1)); } for(i=1;i<=n-k+1;i++) { if(i==n-k+1) printf("%d\n",findmax(1,i,i+k-1)); else printf("%d ",findmax(1,i,i+k-1)); } } return 0; }