1. 程式人生 > >codeforces 920F SUM and REPLACE

codeforces 920F SUM and REPLACE

clu 復雜 bre str ++i sum source oid push

codeforces 920F

題目描述

\(d(x)\)為正整數\(x\)的因子的數量。給定一個長度為\(n\)的序列\(a\),有兩種操作:

  1. \([l,r]\)的數i變為\(d(i)\)
  2. \(\sum_{i=l}^{r}{a_i}\)

思路

首先可以用線段樹來維護這個序列,每次暴力修改。因為\(d(1)=1,d(2)=2\),因此當一個區間的最大值小於2時就不需要修改。又因為每次修改只會讓值減少,而每個數最多會被修改\(O(log_2n)\)次,因此能夠保證復雜度

代碼

#include <bits/stdc++.h>

using namespace std;

typedef
long long ll; const int MAXN = 300000 + 10; const int MAXA = 1000000 + 10; const char ENDLINE = \n; int d[MAXA], num[MAXA]; int prime[MAXA / 10], primeCnt; void sieve() { const int MX = 1000000; static bool vis[MAXA]; d[1] = 1; for (int i = 2; i <= MX; ++i) { if (!vis[i]) { prime[++primeCnt] = i; d[i] = 2
; num[i] = 1; } for (int j = 1; j <= primeCnt && prime[j] * i <= MX; ++j) { vis[prime[j] * i] = true; if (i % prime[j] == 0) { num[i * prime[j]] = num[i] + 1; d[i * prime[j]] = d[i] / (num[i] + 1) * (num[i] + 2
); break; } num[i * prime[j]] = 1; d[i * prime[j]] = d[i] * 2; } } } struct SegmentTree { int L[MAXN << 2], R[MAXN << 2]; int mx[MAXN << 2]; ll sum[MAXN << 2]; void pushup(int o) { mx[o] = max(mx[o<<1], mx[o<<1|1]), sum[o] = sum[o<<1] + sum[o<<1|1]; } void update(int l, int r, int o=1) { if (mx[o] <= 2) return; if (L[o] == R[o]) { sum[o] = mx[o] = d[sum[o]]; return; } int mid = (L[o] + R[o]) >> 1; if (l <= mid) update(l, r, o<<1); if (mid < r) update(l, r, o<<1|1); pushup(o); } ll query(int l, int r, int o=1) { if (L[o] == l && R[o] == r) return sum[o]; int mid = (L[o] + R[o]) >> 1; if (r <= mid) return query(l, r, o<<1); if (mid < l) return query(l, r, o<<1|1); return query(l, mid, o<<1) + query(mid+1, r, o<<1|1); } void build(int l, int r, int a[], int o=1) { L[o] = l, R[o] = r; if (l == r) { sum[o] = mx[o] = a[l]; return; } int mid = (l + r) >> 1; build(l, mid, a, o<<1); build(mid+1, r, a, o<<1|1); pushup(o); } } segt; int main() { int n, m; static int a[MAXN]; ios::sync_with_stdio(0); sieve(); cin >> n >> m; for (int i = 1; i <= n; ++i) cin >> a[i]; segt.build(1, n, a); for (int i = 1; i <= m; ++i) { int opt, l, r; cin >> opt >> l >> r; if (opt == 1) { segt.update(l, r); } else { cout << segt.query(l, r) << ENDLINE; } } }

codeforces 920F SUM and REPLACE