이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <stdio.h>
#include <string.h>
#define N 100000
#define N_ (1 << 17) /* N_ = pow2(ceil(log2(N))) */
#define K 32
int aa[N];
int n_; long long cnt[N_ * 2];
int pp[N_ * 2][K], cp[N_ * 2][K], nnp[N_ * 2];
int qq[N_ * 2][K], cq[N_ * 2][K], nnq[N_ * 2];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
long long solve(int *aa, int *cc, int n, int *bb, int *dd, int m) {
int i, j, d;
long long ans;
d = 0, ans = 0;
for (i = n - 1, j = 0, d = 0; i >= 0; i--) {
while (j < m && gcd(aa[i], bb[j]) > 1)
d += dd[j++];
ans += (long long) cc[i] * d;
}
return ans;
}
int merge(int *aa, int *cc, int n, int *bb, int *dd, int m, int *ab, int *cd) {
int j, k, a;
memcpy(ab, aa, n * sizeof *aa), memcpy(cd, cc, n * sizeof *cc);
a = aa[n - 1], k = n;
for (j = 0; j < m; j++) {
a = gcd(a, bb[j]);
if (ab[k - 1] != a)
ab[k] = a, cd[k] = dd[j], k++;
else
cd[k - 1] += dd[j];
}
return k;
}
void pul(int i) {
int l = i << 1, r = l | 1;
cnt[i] = cnt[l] + solve(qq[l], cq[l], nnq[l], pp[r], cp[r], nnp[r]) + cnt[r];
nnp[i] = merge(pp[l], cp[l], nnp[l], pp[r], cp[r], nnp[r], pp[i], cp[i]);
nnq[i] = merge(qq[r], cq[r], nnq[r], qq[l], cq[l], nnq[l], qq[i], cq[i]);
}
void build(int *aa, int n) {
int i;
n_ = 1;
while (n_ < n)
n_ <<= 1;
for (i = 0; i < n_; i++) {
int a = i < n ? aa[i] : 1;
cnt[n_ + i] = a == 1 ? 0 : 1;
pp[n_ + i][0] = a, cp[n_ + i][0] = 1, nnp[n_ + i] = 1;
qq[n_ + i][0] = a, cq[n_ + i][0] = 1, nnq[n_ + i] = 1;
}
for (i = n_ - 1; i > 0; i--)
pul(i);
}
void update(int i, int x) {
cnt[n_ + i] = x == 1 ? 0 : 1;
pp[n_ + i][0] = x, cp[n_ + i][0] = 1;
qq[n_ + i][0] = x, cq[n_ + i][0] = 1;
i += n_;
while (i > 1)
pul(i >>= 1);
}
long long query(int l, int r) {
static int pp_[K], cp_[K], qq_[K], cq_[K], pp1[K], cp1[K], qq1[K], cq1[K];
int np, nq;
long long cntl, cntr;
np = nq = 0, cntl = cntr = 0;
for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) {
if ((l & 1) == 1) {
cntl += solve(qq_, cq_, nq, pp[l], cp[l], nnp[l]) + cnt[l];
nq = merge(qq[l], cq[l], nnq[l], qq_, cq_, nq, qq1, cq1);
memcpy(qq_, qq1, nq * sizeof *qq1), memcpy(cq_, cq1, nq * sizeof *cq1);
l++;
}
if ((r & 1) == 0) {
cntr += cnt[r] + solve(qq[r], cq[r], nnq[r], pp_, cp_, np);
np = merge(pp[r], cp[r], nnp[r], pp_, cp_, np, pp1, cp1);
memcpy(pp_, pp1, np * sizeof *pp1), memcpy(cp_, cp1, np * sizeof *cp1);
r--;
}
}
return cntl + solve(qq_, cq_, nq, pp_, cp_, np) + cntr;
}
int main() {
int n, q, i;
scanf("%d%d", &n, &q);
for (i = 0; i < n; i++)
scanf("%d", &aa[i]);
build(aa, n);
while (q--) {
int t;
scanf("%d", &t);
if (t == 1) {
int x;
scanf("%d%d", &i, &x), i--;
update(i, x);
aa[i] = x;
} else {
int l, r;
scanf("%d%d", &l, &r), l--, r--;
printf("%lld\n", query(l, r));
}
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
garaza.c: In function 'main':
garaza.c:105:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
105 | scanf("%d%d", &n, &q);
| ^~~~~~~~~~~~~~~~~~~~~
garaza.c:107:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
107 | scanf("%d", &aa[i]);
| ^~~~~~~~~~~~~~~~~~~
garaza.c:112:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
112 | scanf("%d", &t);
| ^~~~~~~~~~~~~~~
garaza.c:116:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
116 | scanf("%d%d", &i, &x), i--;
| ^~~~~~~~~~~~~~~~~~~~~
garaza.c:122:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
122 | scanf("%d%d", &l, &r), l--, r--;
| ^~~~~~~~~~~~~~~~~~~~~
# | 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... |