Official
C - Upgrade Required Editorial
by
C - Upgrade Required Editorial
by
physics0523
この解説では、時間計算量 \(O(N+Q)\) の方針を示します。
他の方針も (計算量が少し悪くなるものも含めて) 多く存在します。
まず、バージョン \(X\) 以前の PC をバージョン \(Y\) にアップグレードした時に起きることを整理しましょう。
- 現在の PC のうち最古のバージョンを \(O\) とすると、 \(O\) 以上 \(X\) 以下の全てのバージョンの PC がアップグレードの対象となる。
- 制約より \(X<Y\) なので、このアップグレードが終わると、 \(X\) 以前のバージョンの PC は存在しなくなる。
- 以降のアップデートに対して、 \(O=X+1\) 以上になる。
このことから、最古のバージョン \(O\) に着目しながらアップグレードを行うと高速にアップグレードを処理できそうです。
ここから、以下の解法が成り立ちます。
- 最初、最古のバージョンは \(O=1\) である。
- \(i=1,2,\dots,Q\) について、 \(i\) 回目の操作を行う。
- \(X_i < O\) である時、 \(X_i\) 以前のバージョンの PC はもう存在しないのでこの操作をスキップする。
- そうでない時、 \(O \le X_i\) である限り次の操作を繰り返す。
- バージョン \(O\) の PC を全てバージョン \(Y_i\) にアップグレードする。
- その後、 \(O \rightarrow O+1\) とする。
一連の解法は、配列とループの組み合わせで表現できます。
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,q;
cin >> n >> q;
vector<int> pc(n+1,1);
pc[0]=0;
int o=1;
while(q--){
int x,y;
cin >> x >> y;
int res=0;
while(o<=x){
res+=pc[o];
pc[y]+=pc[o];
o++;
}
cout << res << "\n";
}
return 0;
}
posted:
last update:
