【例と結論】【単調キュー(スライドウィンドウ)】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は求められています.
//    STL
#include
#include
using namespace std;
const int need=1000004;

struct fy{int id,u;}a;
int ans1[need],ans2[need];
dequez,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])
)