【例と結論】【単調キュー(スライドウィンドウ)】NKOJ 2152スライドウィンドウ
NKOJ 2152スライドウィンドウ時間制限:10000 MS空間制限:65536 KB
問題は、長さN(N<=10^6)の配列を説明します.長さKのスライドのフォームは一番左から一番右に移動します.ウィンドウのK個の数しか見られません.フォームごとに1桁右に移動します.フォームに含まれる数字の最大値と最小値は下記の表の通りです.kの値は3です.
ウィンドウの位置の最小値の最大値
[1-3-1]-3 3 3 3 6-1 1[3-1-3]5 3 6-3 1 3 3 3[-1-3 5]3 6-3 1 3 3 3 3 3-1 3 3 3 3]-1[-3 5 3 3]6-3 1-3 3 3 3 3-3[5]7 6 6 6-1 3 3 3-3[3 7]3
フォーマット1行目n,k,2行目の長さnの配列を入力します.
出力フォーマットは2行で、1行目は各位置のmin value、2行目は各位置のmax valueです.
サンプル入力8 3 1-3-1-3 3 3 6 7
サンプル出力-1-3-3 3 3 3 3 5 5 7
ソースpoj 2823
構想:maxを求めて、単調な減少列を維持して、もしtop>現在の値ならば、pop、そしてpsh現在の値.もっとpop_backは区間外の要素を検討していますが、最後のbackは求められています.
問題は、長さN(N<=10^6)の配列を説明します.長さKのスライドのフォームは一番左から一番右に移動します.ウィンドウのK個の数しか見られません.フォームごとに1桁右に移動します.フォームに含まれる数字の最大値と最小値は下記の表の通りです.kの値は3です.
ウィンドウの位置の最小値の最大値
[1-3-1]-3 3 3 3 6-1 1[3-1-3]5 3 6-3 1 3 3 3[-1-3 5]3 6-3 1 3 3 3 3 3-1 3 3 3 3]-1[-3 5 3 3]6-3 1-3 3 3 3 3-3[5]7 6 6 6-1 3 3 3-3[3 7]3
フォーマット1行目n,k,2行目の長さnの配列を入力します.
出力フォーマットは2行で、1行目は各位置のmin value、2行目は各位置のmax valueです.
サンプル入力8 3 1-3-1-3 3 3 6 7
サンプル出力-1-3-3 3 3 3 3 5 5 7
ソースpoj 2823
構想:maxを求めて、単調な減少列を維持して、もしtop>現在の値ならば、pop、そしてpsh現在の値.もっとpop_backは区間外の要素を検討していますが、最後のbackは求められています.
// STL
#include
#include
using namespace std;
const int need=1000004;
struct fy{int id,u;}a;
int ans1[need],ans2[need];
deque z,j;
inline void in_(int &d)
{
bool mark=false;char t=getchar();
while(t<'0'||t>'9'){if(t=='-') mark=true;t=getchar();}
for(d=0;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)-'0'+t;
if(mark) d=-d;
}
char o[100];
inline void out_(int x)
{
int l=1;
if(x<0) x=-x,putchar('-');
if(!x) putchar('0');
for(;x;x/=10) o[l++]=x%10+'0';
for(l--;l;l--)putchar(o[l]);
putchar(' ');
}
int main()
{
int n,k;scanf("%d%d",&n,&k);
for(int i=1;i//scanf("%d",&a.u);
a.id=i;
while(z.size()>0&&z.back().u>=a.u) z.pop_back();
z.push_back(a);
while(j.size()>0&&j.back().u<=a.u) j.pop_back();
j.push_back(a);
}
for(int i=1;i<=n-k+1;i++)
{
in_(a.u);//scanf("%d",&a.u);
a.id=i+k-1;
while(z.size()>0&&z.back().u>=a.u) z.pop_back();
z.push_back(a);
while(j.size()>0&&j.back().u<=a.u) j.pop_back();
j.push_back(a);
while(z.size()>0&&z.front().idwhile(j.size()>0&&j.front().idfor(int i=1;i<=n-k+1;i++) out_(ans1[i]);//printf("%d ",ans1[i]);
puts("");
for(int i=1;i<=n-k+1;i++) out_(ans2[i]);//printf("%d ",ans2[i]);
}
// &
#include
#include
using namespace std;
const int need=(1e6)+5;
typedef int deq[need];
deq dqmax,dqmin;
int topmax,backmax=1,topmin,backmin=1;
int a[need],ansmax[need]={-1e9},ansmin[need]={1e9};
inline void in_(int &d)
{
bool mark=false;char t=getchar();
while(t<'0'||t>'9'){if(t=='-') mark=true;t=getchar();}
for(d=0;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)-'0'+t;
if(mark) d=-d;
}
char o[100];
inline void out_(int x)
{
int l=1;
if(x<0) x=-x,putchar('-');
if(!x) putchar('0');
for(;x;x/=10) o[l++]=x%10+'0';
for(l--;l;l--)putchar(o[l]);
putchar(' ');
}
int main()
{
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int n,k;scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
in_(a[i]);//scanf("%d",&a[i]);
while(topmax!=backmax-1&&a[dqmax[topmax]]while(topmin!=backmin-1&a[dqmin[topmin]>a[i]topmin--
dqmax[++topmax]=i
dqmin[++topmin]=i
ansmax[i]=max(a[i],ansmax[i-1])
ansmin[i]=min(a[i],ansmin[i-1])
)
for(int i=k+1;i<=n;i+)
{
n_(a[i])///scanf(“%d”,&a[i]);
while(topmax!=backmax-1&a[dqmax[topmax]while(topmin!=backmin-1&a[dqmin[topmin]>a[i]topmin--
dqmax[++topmax]=i
dqmin[++topmin]=i
if(topmax!=backmax-1&dqmax[backmax]1)backmax+;
if(topmin!=backmin-1&dqmin[backmin]1)backmin+;
ansmax[i]=a[dqmax[backmax]
ansmin[i]=a[dqmin[backmin]
)
for(int i=k;i==n;i+)out_(ansmin[i])///printf(「%d」、ansmin[i])
putar(10)
for(int i=k;i==n;i+)out_(ansmax[i])///printf(「%d」、ansmax[i])
)