codeforces 920F SUM and REPLACE
阿新 • • 發佈:2018-05-14
clu 復雜 bre str ++i sum source oid push
codeforces 920F
題目描述
令\(d(x)\)為正整數\(x\)的因子的數量。給定一個長度為\(n\)的序列\(a\),有兩種操作:
- 將\([l,r]\)的數i變為\(d(i)\)
- 求\(\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