大家都知道的单调队列模板题
被卡时间了,难受
poj上G++过不去 只能换C++
简单解释一下,单调队列就是去头(过期信息)+去尾(冗余信息)
放到这题就是每次更新去掉前面加入时间太早的,再去掉后面又早加入又离要求的最值远的
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
using namespace std;
#define getchar() (frS==frT&&(frT=(frS=frBB)+fread(frBB,1,1<<12,stdin),frS==frT)?EOF:*frS++)
char frBB[1<<12]={},*frS=frBB,*frT=frBB;
int N,K,head=1,head2=1;
int lst[1000005]={};
int tme[1000005]={};
int ans[1000005]={};
int lst2[1000005]={};
int tme2[1000005]={};
inline int read()
{
bool w=0;int x=0;char ch=getchar();
while(!isdigit(ch))w|=(ch=='-'),ch=getchar();
while(isdigit(ch))x=x*10+(ch-'0'),ch=getchar();
return w?-x:x;
}
int main()
{
N=read(); K=read();
for(register int tmp,i=1;i<=N;++i)
{
tmp=read();
lst[0]=lower_bound(lst+head,lst+1+lst[0],-tmp)-lst;
lst[lst[0]]=-tmp; tme[lst[0]]=i;
head=upper_bound(tme+head,tme+1+lst[0],i-K)-tme;
if(i>=K)ans[++ans[0]]=-lst[head];
lst2[0]=lower_bound(lst2+head2,lst2+1+lst2[0],tmp)-lst2;
lst2[lst2[0]]=tmp; tme2[lst2[0]]=i;
head2=upper_bound(tme2+head2,tme2+1+lst2[0],i-K)-tme2;
if(i>=K)printf("%d ",lst2[head2]);
}
putchar('\n');
for(register int i=1;i<=ans[0];++i)printf("%d ",ans[i]);
return 0;
}
upper_bound和lower_bound有那么慢吗((
不过改成手写二分也是tle
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
using namespace std;
#define getchar() (frS==frT&&(frT=(frS=frBB)+fread(frBB,1,1<<12,stdin),frS==frT)?EOF:*frS++)
char frBB[1<<12]={},*frS=frBB,*frT=frBB;
int N,K,head=1,head2=1;
int lst[1000005]={};
int tme[1000005]={};
int ans[1000005]={};
int lst2[1000005]={};
int tme2[1000005]={};
inline int read()
{
bool w=0;int x=0;char ch=getchar();
while(!isdigit(ch))w|=(ch=='-'),ch=getchar();
while(isdigit(ch))x=x*10+(ch-'0'),ch=getchar();
return w?-x:x;
}
int lowb(int* array,int l,int r,int key)
{
register int mid; ++r;
while(l<r)
{
mid=l+r>>1;
if(array[mid]<key)l=mid+1;
else r=mid;
}
return l;
}
int main()
{
N=read(); K=read();
for(register int tmp,i=1;i<=N;++i)
{
tmp=read();
lst[0]=lowb(lst,head,lst[0],-tmp);
lst[lst[0]]=-tmp; tme[lst[0]]=i;
while(tme[head]<=i-K)++head; //这里上面的代码不该二分的
if(i>=K)ans[++ans[0]]=-lst[head];
lst2[0]=lowb(lst2,head2,lst2[0],tmp);
lst2[lst2[0]]=tmp; tme2[lst2[0]]=i;
while(tme2[head2]<=i-K)++head2;
if(i>=K)printf("%d ",lst2[head2]);
}
putchar('\n');
for(register int i=1;i<=ans[0];++i)printf("%d ",ans[i]);
return 0;
}