传送门
题意:给n个数,还有个k,让你输出从前往后每k个数的最大和最小值。
思路:线段树随意搞了下。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define maxn 1<<30 using namespace std; struct node { int l,r; int mi,ma; }t[5000000]; int n,k,a[1000005],ami[1000005],ama[1000005]; int in() { char ch; int aa=0; bool ff=0; while((ch=getchar())==' '||ch=='\n'); if(ch=='-') { ff=1; } else aa += ch - '0'; while((ch=getchar())!=' '&&ch!='\n') { aa*=10; aa+=ch-'0'; } if(ff)return -aa; else return aa; } void out(int aa) { if(aa<0) { putchar('-'); aa=-aa; } if(aa>=10)out(aa/10); putchar(aa%10+'0'); } void build(int ll,int rr,int rot) { t[rot].l=ll; t[rot].r=rr; if(ll==rr) { t[rot].mi=a[ll]; t[rot].ma=a[ll]; } else { int mid=(ll+rr)/2; build(ll,mid,rot<<1); build(mid+1,rr,rot<<1|1); t[rot].mi=min(t[rot<<1].mi,t[rot<<1|1].mi); t[rot].ma=max(t[rot<<1].ma,t[rot<<1|1].ma); } } void query(int ll,int rr,int rot,int m) { if(ll<=t[rot].l&&rr>=t[rot].r) { ami[m]=min(ami[m],t[rot].mi); ama[m]=max(ama[m],t[rot].ma); } else { int mid=(t[rot].l+t[rot].r)/2; if(rr<=mid) { query(ll,rr,rot<<1,m); } else if(ll>mid) { query(ll,rr,rot<<1|1,m); } else { query(ll,mid,rot<<1,m); query(mid+1,rr,rot<<1|1,m); } } } int main() { n=in(); k=in(); for(int i=1;i<=n;i++) { a[i]=in(); } build(1,n,1); for(int i=k;i<=n;i++) { ami[i]=maxn; ama[i]=-maxn; query(i-k+1,i,1,i); } out(ami[k]); for(int i=k+1;i<=n;i++) { putchar(' '); out(ami[i]); } putchar('\n'); out(ama[k]); for(int i=k+1;i<=n;i++) { putchar(' '); out(ama[i]); } putchar('\n'); return 0; }