結果
| 問題 |
No.1036 Make One With GCD 2
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-03-14 05:20:47 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,096 bytes |
| コンパイル時間 | 1,937 ms |
| コンパイル使用メモリ | 175,044 KB |
| 実行使用メモリ | 29,008 KB |
| 最終ジャッジ日時 | 2024-11-07 01:57:01 |
| 合計ジャッジ時間 | 10,085 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 4 |
| other | TLE * 1 -- * 40 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define SPEED cin.tie(0);ios::sync_with_stdio(false);
#include <bits/stdc++.h>
using namespace std;
template<class T> class Segment_Tree_Range_Gcd_Query {
size_t N,M;
T ini;
vector<T> node;
public:
Segment_Tree_Range_Gcd_Query(const vector<T> & ar, const T ini) : M(ar.size()), ini(ini) {
for (N = 1; N < M; N *= 2);
node.resize(2 * N - 1, ini);
for (int i = 0; i<M; ++i) node[i + N - 1] = ar[i];
for (int i = N - 2; i >= 0; --i) node[i] = Gcd(node[2 * i + 1], node[2 * i + 2]);
}
Segment_Tree_Range_Gcd_Query(const size_t M, const T ini) : M(M), ini(ini) {
for (N = 1; N < M; N *= 2);
node.resize(2 * N - 1, ini);
}
void update(size_t idx, const T var) {
idx += (N - 1);
node[idx] = var;
while (idx > 0) {
idx = (idx - 1) / 2;
node[idx] = Gcd(node[2 * idx + 1], node[2 * idx + 2]);
}
}
T getvar(const int a, const int b, int k = 0, int l = 0, int r = -1) {
if (r < 0) r = N;
if (r <= a || b <= l) return ini;
if (a <= l && r <= b) return node[k];
T vl = getvar(a, b, 2 * k + 1, l, (l + r) / 2);
T vr = getvar(a, b, 2 * k + 2, (l + r) / 2, r);
return Gcd(vl, vr);
}
//Greatest Common Divisor
T Gcd(T a, T b) {
return ((b == 0) ? a : Gcd(b, a % b));
}
T operator[](size_t idx) {
return node[idx + N - 1];
}
T operator[](pair<size_t, size_t> p) {
return getvar(p.first, p.second);
}
void print() {
cout << "{ " << getvar(0, 1);
for (int i = 1; i < M; ++i) cout << ", " << getvar(i, i + 1);
cout << " }" << endl;
}
};
// TLE solution by N*(logN)^2*(logA)
int main() {
SPEED
ll N; cin >> N;
vector<ll> A(N+1,1);
for(int i = 0; i < N; ++i) cin >> A[i];
Segment_Tree_Range_Gcd_Query<ll> seg(A,0);
ll ans = 0;
for(int i = 0; i < N; ++i) {
if(A[i] == 1){
ans += (N-i);
}
else{
int ok = N,ng = i,md;
while(ok-ng>1){
md = (ok+ng)/2;
(seg.getvar(i,md+1)==1?ok:ng)=md;
}
ans += (N-ok);
}
}
cout << ans << endl;
}