「CF 1180C」 Valeriy and Deque
阿新 • • 發佈:2021-07-08
題目大意
給定一個雙端佇列,然後給定一個 \(operationn\),每一個 \(operation\) 可以實現以下步驟:
取出佇列的前兩個元素,分別是 \(A\),\(B\)。
如果 \(A>B\),那麼 \(A\) 加入到這個佇列的 \(front\),\(B\) 加入到 \(back\),否則 \(A\) 加入 \(back\),B加入 \(front\)。,然後給你 \(q\) 個詢問,每一個詢問是問你從原始陣列開始執行第 \(x\) 次 \(operation\) 時,\(A\) 和 \(B\) 分別是多少?
分析
首先想到用 \(deque\) 模擬,但肯定會超時。
注意到當最大數被操作到首位後就不會再移動,那剩下的數就會形成迴圈。
所以我們只需要用 \(deque\)
#include<bits/stdc++.h> using namespace std; const int M=2e5+5; int n,m,_max; int lst,x[M],y[M],b[M]; deque<int> G; int main(){ scanf("%d %d",&n,&m); for(int i=1,x;i<=n;i++){ scanf("%d",&x); _max=max(_max,x); G.push_back(x); } int now=0; while(1){ if(G.front()==_max) break;//判斷首位是否最大值 int p=G.front(); G.pop_front(); int q=G.front(); G.pop_front();//模擬 x[++now]=p; y[now]=q; if(p<q) swap(p,q); G.push_front(p); G.push_back(q); } if(G.size()) G.pop_front(); while(G.size()){//求迴圈節 b[++lst]=G.front(); G.pop_front(); } for(int i=1;i<=m;i++){ long long o; scanf("%lld",&o); if(o<=now){ printf("%d %d\n",x[o],y[o]); continue; } else{ o-=now; printf("%d %d\n",_max,b[(o-1)%(n-1)+1]); } } }