KD的单调队列啊!! 十分坑啊~~ 整个下午都浪费在这个上面了~虽然优化到了5400ms+了,但是离那些500ms+的神犇们差距太远了... 应该是有很好的算法吧,只能一个人想了。
使用单调队列... 无限TLE啊... 没看代码只是自己YY了一遍大概怎么弄。我理解的的单调队列大概是这个样子。
拿样例来说事吧。觉得类似于网络协议中的窗口协议。
8 3 1 3 -1 -3 5 3 6 7窗口大小为3
每次更新单调队列
1.{ 1 };
2.{ 1,3 };
3.{ -1 }; 输出-1
4.{ -3 };输出-3
5.{ -3,5 };输出-3
6.{ -3,3 };输出-3
7.{ 3 }->{ 3,6 };输出3
8.{ 3,6,7 };输出3
同样地对于max序列。
可见规律为:每次输出队头元素,当前元素从队尾走向队头,插入第一个符合条件的地方。保证队列单调,而且相同的元素尽可能的大,这样每次维持一个队列。输出最前段的元素。但是判断插入的时候不能从前面向后扫描,这样时间开销太大了我就果断的TLE了一下午,查不出错误,后来就队尾向前扫一遍,找到节点插入就行了。
KD的单调队列啊~~
#include<iostream>
#define MAXN 1000005
using namespace std;
int date[MAXN];
int temp[MAXN];
int main()
{
int n,c;
int foot=1;
int index=1;
int i,pre;
while( scanf( "%d %d",&n,&c )!=EOF )
{
memset( date,0,sizeof(date) );
memset( temp,0,sizeof(temp) );
for( i=1;i<=n;i++ )
scanf( "%d",&date[i] );
//memset( temp,0,sizeof(temp) );
temp[1]=1;
foot=2;index=1;
for( i=1;i<=n;i++ )
{
if( i-temp[index]+1>c )
index++;
pre=foot;
while(1)
{
if( date[i]<=date[temp[pre-1]]&& pre-1>=index )
pre--;
else
break;
}
foot=pre+1;
temp[pre]=i;
if( i==c )
printf( "%d",date[temp[index]] );
if( i>c )
printf( " %d",date[temp[index]] );
}
printf( "\n" );
foot=2;index=1;
temp[1]=1;
for( i=1;i<=n;i++ )
{
if( i-temp[index]+1>c )
index++;
pre=foot;
while(1)
{
if( date[i]>=date[temp[pre-1]]&&pre-1>=index )
pre--;
else
break;
}
foot=pre+1;
temp[pre]=i;
if( i==c )
printf( "%d",date[temp[index]] );
if( i>c )
printf( " %d",date[temp[index]] );
}
printf( "\n" );
}
return 0;
}