結果
| 問題 | No.1036 Make One With GCD 2 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-05-30 15:55:17 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 1,878 bytes |
| 記録 | |
| コンパイル時間 | 3,049 ms |
| コンパイル使用メモリ | 201,012 KB |
| 実行使用メモリ | 25,856 KB |
| 最終ジャッジ日時 | 2024-11-07 18:40:01 |
| 合計ジャッジ時間 | 11,912 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 4 |
| other | TLE * 1 -- * 40 |
ソースコード
#pragma GCC optimize("O3", "unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
inline ll gcd(ll a, ll b){
if (b > a) return gcd(b, a);
if (b == 0) return a;
return gcd(b, a % b);
}
template<typename T>
struct SegmentTree {
private:
int sz, n;
vector<T> data;
function<T(T, T)> f;
T identity_element;
public:
/* constructor */
SegmentTree(
vector<T>& v, // initial data
T identity_element, // identity element
function<T(T, T)> f // operation
) {
sz = v.size();
n = 1; while (n < sz) n <<= 1;
this->f = f;
this->identity_element = identity_element;
data.resize(2 * n - 1, identity_element);
for (int i = 0; i < sz; ++i)
data[i + n - 1] = v[i];
for (int i = n - 2; i >= 0; --i)
data[i] = f(data[2 * i + 1], data[2 * i + 2]);
}
/* update query */
void update(int idx, const T val) {
idx += n - 1;
data[idx] = val;
while (idx) {
idx = (idx - 1) >> 1;
data[idx] = f(data[2 * idx + 1], data[2 * idx + 2]);
}
}
/* get query */
T get(int left, int right, int k = 0, int l = 0, int r = -1) {
if (r < 0) r = n;
if (r <= left || right <= l) return identity_element;
if (left <= l && r <= right) return data[k];
T val_l = get(left, right, 2 * k + 1, l, (l + r) / 2);
T val_r = get(left, right, 2 * k + 2, (l + r) / 2, r);
return f(val_l, val_r);
}
};
int main(void){
int N; cin >> N;
vector<ll> A(N);
for (int i = 0; i < N; ++i)
cin >> A[i];
SegmentTree<ll> seg(
A, 0LL, [](ll a, ll b){
return gcd(a, b);
}
);
ll res = 0;
for (int i = 0; i < N; ++i){
if (seg.get(i, N) > 1) continue;
if (A[i] == 1){
res += N - i;
continue;
}
int ng = i + 1, ok = N;
while (ok - ng > 1){
int mid = (ok + ng) / 2;
if (seg.get(i, mid) > 1) ng = mid;
else ok = mid;
}
res += N - ok + 1;
}
cout << res << endl;
return 0;
}