POJ 2823(線段樹)
阿新 • • 發佈:2019-02-12
題意
給出一個n個數的序列和區間長度k,讓你輸出每個長度為k區間內的最大值和最小值,順序是從左往右。
解題思路
這是單調佇列的題,但看了這個題的時間12000ms,感覺能用BST搞一搞。交了一發TLE,後來看到discuss裡面有人說BST要用C++提交,然後原封不動的用C++提交,過了。而且很莫名其妙,我用輸入外掛比我不用輸入外掛慢了接近2000ms。。。
程式碼
/*
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 永無BUG
*/
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
struct node
{
int minn,maxx;
} arr[maxn<<2];
void pushup(int rt)
{
arr[rt].minn=min(arr[rt<<1].minn,arr[rt<<1|1].minn);
arr[rt].maxx=max(arr[rt<<1 ].maxx,arr[rt<<1|1].maxx);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&arr[rt].minn);
arr[rt].maxx=arr[rt].minn;
return;
}
int m=l+r>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}
int querymin(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return arr[rt].minn;
int m=l+r>>1,ans=inf;
if(L<=m) ans=min(ans,querymin(L,R,l,m,rt<<1));
if(R> m) ans=min(ans,querymin(L,R,m+1,r,rt<<1|1));
return ans;
}
int querymax(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return arr[rt].maxx;
int m=l+r>>1,ans=-inf;
if(L<=m) ans=max(ans,querymax(L,R,l,m,rt<<1));
if(R> m) ans=max(ans,querymax(L,R,m+1,r,rt<<1|1));
return ans;
}
int main()
{
#ifdef DEBUG
freopen("in.txt","r",stdin);
#endif // DEBUG
int n,k;
scanf("%d%d",&n,&k);
build(1,n,1);
for(int i=1; i<n-k+2; i++)
printf("%s%d",i==1?"":" ",querymin(i,i+k-1,1,n,1));
printf("\n");
for(int i=1; i<n-k+2; i++)
printf("%s%d",i==1?"":" ",querymax(i,i+k-1,1,n,1));
printf("\n");
return 0;
}