m区間の最小値を求めます


タイトルの説明
n項を含む数列(n<=200000,000)は、各項の前のm個数からその区間内の最小値を求める.前の数がm項未満であれば1番目の数から、前に数がなければ0を出力します.
にゅうしゅつりょくけいしき
入力形式:
最初の行の2つの数n,m.
2行目、n個の正の整数は、与えられた数列である.
出力フォーマット:
n行目、i行目の1つの数aiは、求めたシーケンスのi番目の数より前のm番目の数の最小値である.
入出力サンプル
入力サンプル#1:コピー
6 2
7 8 1 4 3 2

出力サンプル#1:コピー
0
7
7
1
1
3 

説明
【データ規模】
m≤n≤2000000
構想:上昇シーケンスの単調なキューを維持する必要があります.kがa[tail]より小さいことを発見したら前に置いて、他は要らないで、彼らより小さいkがあるので、kより小さいものがあれば、きっと彼らより小さいに違いない.
注意:問題の要求は前で、現在のものを一緒に比較しないでください(もちろん私のように先に前のものを完成したり入力したりして先に保存して、次のサイクルで使うこともできます.
コード:
//a[]は入力された値を表し、b[i]はこのa[i]の入力中の元のシーケンス番号を表す.
#include
#include #include
int n,m,k,head=0,tail=0;int a[100000],b[100000];
using namespace std;
int Input()/入力最適化
{
    char c=getchar();
    int n=0;
    while(c  < '0' || c  > '9') c=getchar();
    while(c >= '0' && c <= '9') n=(n << 1)+(n << 3)+(c-48) , c=getchar();
    return n;
}
int main()【かっこだ!!!0じゃない!!】
 {
    n=Input();m=Input();
 
printf("0");//先出力0
 
a[tail]=Input();
 
++tail;
 
for(int i=1;i
{
     while(b[head]      printf("%d",a[head]);//出力キュートップ、つまり最小の
     k=Input();
while(a[tail-1]>k&&tail>head)/入力した値がa[tail]より小さい場合は、値を前に置きます.-1の原因は、以前はtail++があったので、自分で令の書き方を変えることができましたが、不安定かもしれません(前に2回waしました)
      tail--;
     a[tail]=k;
     b[tail]=i;
     ++tail;
     }
  
 }