最近では、アルゴリズムとデータ構造のコースで、バレリーは、両端キューを使用する方法を学びました。彼は、n個の要素で満たさ両端キューを構築しました。i番目の要素は、AI(I = 1,2、...、N)です。彼は徐々に(それぞれのは、AとB、それらを呼びましょう)両端キューから最初の二つの左端の要素を取り、その後、次の処理を行います。A> Bならば、彼はそれ以外の場合は、先頭に書き込み、両端キューの末尾にBを書き込み、彼は最初Bに書き込み、そしてAは両端キューの末尾に書き込みます。私たちは、操作のアクションのこのシーケンスを呼び出します。
例えば、両端キューは、[2,3,4,5,1]だった場合は、操作に彼は最後まで先頭とA = 2にB = 3を書きますので、彼は[3,4,5,1を取得します、2]。
彼の仕事に情熱だったバレリーを、見てのコースの教師は、彼に近づき、彼にQクエリを与えました。各クエリは、単数のMJ(J = 1,2、...、Q)からなります。彼がMJ番目の操作を引き出しますこれは2つの要素を答えるためにクエリごとに必要です。
ことに留意されたい クエリは独立しており 、それぞれの数値AおよびBがされるべきクエリ それらは両端キューから引き出さされる順序で印刷。
両端キューは、 既存の要素の新しい要素又は欠失の挿入を両側から作ることができる要素のリストを表すデータ構造です。
入力
両端キュー内の要素の数とクエリの数 - 最初の行は二つの整数nおよびQ(2≤n≤105、0≤q≤3⋅105)を含みます。i番目の位置にある両端キュー要素 - 2行目は、n個の整数のA1、A2、...、AI(0≤ai≤109)を含みます。次qlinesはMJ(1≤mj≤1018)を意味し、1つの番号毎に含まれています。
出力
各教師のクエリに対して、出力2つの数AとB - バレリーがMJ番目の動作に両端キューからプル数。
例
入力
5 3
1 2 3 4 5
1
2
10
出力
1 2
2 3
5 2
入力
2 0
0 0
出力
注意
詳細最初のテストのためのすべての10個のステップを考えてみましょう:
- [1,2,3,4,5] - 最初の操作で、A及びBは、それぞれ1,2です。
だから、2我々は両端キューの先頭に書き込み、1 - 最後に。
[2,3,4,5,1]:私たちは、両端キューの次のステータスを取得します。
2. [2,3,4,5,1]⇒A= 2、B = 3。
3. [3,4,5,1,2]
4. [4,5,1,2,3]
5. [5,1,2,3,4]
6. [5,2,3,4,1]
7. [5,3,4,1,2]
8. [5,4,1,2,3]
9. [5,1,2,3,4]
10 [5,2,3,4,1]⇒A= 5、B = 2。
問題の意味:タイトル数n使用すると、1つの操作を持つ両端キューを置くことを意味します:小さなまたは放電後のと同じ大きさの多数の前に置く2つの数値を、削除する前に、あなたは操作m回の後に尋ねますはい前にどのような二つの数字。
考える:両端キュービットとして研究を、良い感じ(もorzorzません前に、私は、より多くの野菜を午前)、我々は見つけることができます説明のサンプルを見ることで、
最初のチームの両端キューは、いくつかの操作の後に最大となり、その後、N-1回後の同じサイクルの結果で動作する場合
尾に第一及び第二の数際にチーム内の最大値は、この状況を理解した後、操作しなければならないので、
前処理液の前部を循環させず、サイクルが直接出力することができた後、我々は解決策の一部のみを必要とする......
1の#include <iostreamの>
2の#include <CStringの>
3の#include <cstdioを>
4の#include <cmath>
5の#include <アルゴリズム>
6の#include <地図>
7の#include < 設定 >
8の#include <ベクトル>
9#含める<キュー>
10 使って 名前空間はstdを、
11 の#defineっ長い長い
12 のconst int型 MOD = 1E9 + 7 。
13 のconst int型 INF = 1E9 + 7 。
14
15両端キュー< int型> D; // 両端キュー
16
。17 INT メイン()
18である {
19。 IOSの::(sync_with_stdio はfalse); cin.tie(0); cout.tie(0 );
20である
21れる )(d.clear;
22である
23れる INT N、OP;
24 ; CIN >> N-OP // 数N、OP操作
25
26である INT -マックス= 1 ; // の最大値を見つける
27 のint NUMを、
28 のために(INT I = 0 ; I <N- ; I ++ )
29 {
30 CIN >> NUM; // 入力
31は、 IF(NUM> マックス)
32 ;マックスNUMが= // 最大値更新
33がある d.push_back(NUM); // 尾部は両端キュー導入
34である }
35
36 IF = OP( = 0)// 公報決意波
37 [ リターン 0 、
38は
39 のベクトル<ペア< INT、INT >> V1; // 前の溶液のこの記憶されているループのない部分
40 のベクトル<ペア< INT、INT >> V2。// この溶液の一部は、後にループバック維持される
41は
42である (v1.clear);
43である v2.clear();
44れる
45 INT A、B;
46である
47 ながら(D [ 0!] =マックス)// 最初の前処理部分見つけるためのソリューション
48 {
49 A = Dを[ 0 ]; // 最初の数である
50 B = Dの[ 1 ]; // B番目の文字さ
51は
52である (d.pop_front);
53である D. pop_front();
54である // 動作両端キュー波を意図タイトル
55 IF(A> B)
56であります {
57は d.push_front(A);
58 d.push_back(B);
59 }
60 他
61れる {
62である d.push_front(B)
63は d.push_back(A);
64 }
65
66 v1.push_back({A、 } B); // 動作v1配列に導入溶液
67
68 }
69
70 // のための(I = 0 int型、Iは(v1.sizeを<); Iは++)//は溶液の前部に見ることができる
71は、 // << COUT V1 [I] 1次回<< "" << V1 [I] .second << ENDL;
72
73は、 LLのINT= N- xunhuan 1。 ; // セクション長の部分の後のサイクル
74
75 LL INT M = v1.size(); // 溶液の前部の長さ
76
77 のために(INT I = 0 ; I <xunhuan; Iは++)// ループ処理部
78 {
79 A = D [ 0 ];
80 B = Dの[ 1 ];
81 d.pop_front();
82 d.pop_front();
83
84 IF(A> B)
85 {
86 d.push_front (A)。
87 d.push_back(B);
88 }
89 他の
90 {
91は d.push_front(B);
92 d.push_back(A);
93 }
94
95 v2.push_back({A、B});
96 }
97
98 / / 用(INT I = 0;私は<v2.size();私は++)// サイクルの部分が溶液の後部を見ることができる
99 // COUT << V2 [I] 1次回<< "" << V2 [ I] .second << ENDL;
100
101 LLのINTのcaozuo;
102
103 のための(INT I = 0; I <OPを、Iは++ )
104 {
105 CIN >> caozuo;
106
107 IF(caozuo> = 1 && caozuo <= v1.size())//は最初の部分の溶液で
108 {
109 COUT << V1 [caozuo- 1。 ] 1次回<< " " << V1 [caozuo- 1。 ] .second << ENDL;
110 }
111 そう
112 {
113 caozuo- v1.size =(); // ここで再びフィルムループ部を失い、%% %
114 caozuo%= xunhuan;
115 IF(caozuo == 0)// 0-1越界了、特判一下orzorz
116 COUT << V2 [v2.size() - 1 ] 1次回<< " " << V2 [v2.size() - 1 ] .second << てendl;
117 そう
118 COUT << V2 [caozuo- 1 ] 1次回<< " " << V2 [caozuo- 1 ] .second << ENDL。
119 }
120
121 }
122
123 リターン 0 。
124 }