結果
| 問題 |
No.1036 Make One With GCD 2
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2021-08-02 23:11:56 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 418 ms / 2,000 ms |
| コード長 | 1,676 bytes |
| コンパイル時間 | 700 ms |
| コンパイル使用メモリ | 71,808 KB |
| 実行使用メモリ | 11,264 KB |
| 最終ジャッジ日時 | 2024-09-16 14:48:47 |
| 合計ジャッジ時間 | 10,549 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 41 |
ソースコード
#include <cstdio>
#include <vector>
#include <cassert>
#include <iostream>
#include <cstdint>
#include <chrono>
using namespace std;
#define I64 int64_t
#define curtime chrono::system_clock::time_point
#define getcurtime chrono::system_clock::now
I64 getgcd(I64 x, I64 y)
{
I64 t;
while(0 < x){
t = x;
x = y % x;
y = t;
}
return y;
}
I64 a[500010];
int suf_spos;
I64 pre_sum[500010];
I64 suf_sum;
int pre_idx_len;
int suf_len;
void push(int idx)
{
suf_len++;
if(suf_len == 1){
suf_spos = idx;
suf_sum = a[idx];
} else {
suf_sum = getgcd(suf_sum, a[idx]);
}
}
void pop()
{
if(pre_idx_len == 0){
I64 v = a[suf_spos + suf_len - 1];
pre_sum[0] = v;
for(int i = 2; i < suf_len; i++){
v = getgcd(v, a[suf_spos + suf_len - i]);
pre_sum[i - 1] = v;
}
pre_idx_len = suf_len - 1;
suf_len = 0;
} else {
pre_idx_len--;
}
}
I64 query()
{
if(pre_idx_len == 0){
return suf_sum;
} else if(suf_len == 0){
return pre_sum[pre_idx_len - 1];
} else {
return getgcd(suf_sum, pre_sum[pre_idx_len - 1]);
}
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
for(int i = 0; i < n; i++){
I64 v;
cin >> v;
a[i] = v;
}
a[n] = 1;
suf_spos = 0;
suf_sum = 0;
pre_idx_len = 0;
suf_len = 0;
I64 ret = 0;
I64 cur = a[0];
int right = 0;
push(0);
for(int i = 0; i < n; i++){
if(right < i){
push(i);
right = i;
cur = a[i];
}
cur = query();
while(1 < cur){
right++;
push(right);
cur = getgcd(cur, a[right]);
}
ret += n - right;
pop();
}
cout << ret << endl;
}