이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
typedef pair<int, int> ii;
const int N = 1e5 + 5;
int n, q, a[N];
struct node {
vector<ii> l, r;
int cnt;
node () : cnt(0) {}
node (int val) {
cnt = (val != 1);
l.clear(); r.clear();
l.push_back(ii(val, 1) ); r.push_back(ii(val, 1) );
}
void add (vector<ii> &_res, vector<ii> _rem) {
if (!_res.size()) return ;
for (auto pa : _rem) {
if (pa.fi % _res.back().fi == 0) _res.back().se = _res.back().se + pa.se;
else _res.push_back(ii(__gcd(pa.fi, _res.back().fi), _res.back().se + pa.se) );
}
}
node operator+(const node& rem) {
node res;
res.cnt = cnt + rem.cnt;
res.l = l; res.r = rem.r;
add (res.l, rem.l); add (res.r, r);
int pter = rem.l.size() - 1;
for (int i = 0; i < r.size(); ++i) {
while (pter >= 0 && __gcd (r[i].fi, rem.l[pter].fi) == 1 ) pter--;
if (pter >= 0) res.cnt += rem.l[pter].se * ( r[i].se - (i ? r[i - 1].se : 0) );
}
return res;
}
};
struct SegmentTree {
node v[4 * N];
void build_tree (int i, int left, int right) {
if (left > right) return ;
if (left == right) {
v[i] = node(a[left]);
return ;
}
int mid = (left + right) >> 1;
build_tree(i << 1, left, mid); build_tree(i << 1 | 1, mid + 1, right);
v[i] = v[i << 1] + v[i << 1 | 1];
}
void update(int i, int left, int right, int pos, int val) {
if (left > right || right < pos || pos < left) return ;
if (left == right) {
v[i] = node (val); return ;
}
int mid = (left + right) >> 1;
update(i << 1, left, mid, pos, val); update(i << 1 | 1, mid + 1, right, pos, val);
v[i] = v[i << 1] + v[i << 1 | 1];
}
node get(int i, int left, int right, int l, int r) {
if (left > right || right < l || r < left) return node();
if (l <= left && right <= r) return v[i];
int mid = (left + right) >> 1;
return get(i << 1, left, mid, l, r) + get(i << 1 | 1, mid + 1, right, l, r);
}
} it;
signed main () {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> q;
for (int i = 1; i <= n; ++i) cin >> a[i];
it.build_tree(1, 1, n);
while (q--) {
int type, x, v; cin >> type >> x >> v;
if (type == 1) it.update(1, 1, n, x, v);
else cout << it.get(1, 1, n, x, v).cnt << '\n';
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
garaza.cpp: In member function 'node node::operator+(const node&)':
garaza.cpp:34:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < r.size(); ++i) {
~~^~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |