Let D(x) be the number of positive divisors of a positive integer x. For example, D(2) = 2 (2 is divisible by 1 and 2), D(6) = 4 (6 is divisible by 1, 2, 3 and 6).
You are given an array a of n integers. You have to process two types of queries:
- REPLACE l r — for every replace ai with D(ai);
- SUM l r — calculate .
Print the answer for each SUM query.
The first line contains two integers n and m (1 ≤ n, m ≤ 3·105) — the number of elements in the array and the number of queries to process, respectively.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the elements of the array.
Then m lines follow, each containing 3 integers ti, li, ri denoting i-th query. If ti = 1, then i-th query is REPLACE li ri, otherwise it's SUM li ri(1 ≤ ti ≤ 2, 1 ≤ li ≤ ri ≤ n).
There is at least one SUM query.
For each SUM query print the answer to it.
7 6 6 4 1 10 3 2 4 2 1 7 2 4 5 1 3 5 2 4 4 1 5 7 2 1 7
30 13 4 22
线段树的应用;
操作1是把范围内所有点变换为此点的因数个数,比如10->4, 5->2, 4->3;
操作2为区间求和;
从操作一中可以发现一个规律,每个点操作一定次数后都会变为2(原始数字为1时保持不变);
所以在树中单开一个maxn数组保存左右儿子的最大值,当最大值小于等于2时直接return进行剪枝,不剪枝会超时;
对于d,可以先进行一个数组预处理,直接枚举出1e6范围内所有数据的d值,方便之后的操作;
直接使用cin,cout会超时;
具体解题方式请看代码;
#include<bits/stdc++.h>
using namespace std;
#define MAX 1000005
#define MAXN 300005
#define ll long long
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define llson rt << 1, l, mid, x, y
#define rrson rt << 1 | 1, mid + 1, r, x, y
int d[MAX], a[MAXN << 2], maxn[MAXN << 2];
ll tree[MAXN << 2];
void init()
{
for(int i = 1; i <= MAX; i++)
for(int j = i; j <= MAX; j += i)
d[j]++;
}
void PushDown(int rt)
{
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
maxn[rt] = max(maxn[rt << 1], maxn[rt << 1 | 1]);
}
void Renewal(int rt)
{
tree[rt] = maxn[rt] = a[rt];
}
void BuildTree(int rt, int l, int r)
{
if(l == r)
{
cin >> a[rt];
Renewal(rt);
return;
}
int mid = (l + r) >> 1;
BuildTree(lson);
BuildTree(rson);
PushDown(rt);
}
void Update(int rt, int l, int r, int x, int y)
{
if(maxn[rt] <= 2)
return;
if(l == r)
{
a[rt] = d[a[rt]];
Renewal(rt);
return;
}
int mid = (l + r) >> 1;
if(mid >= y)
Update(llson);
else if(x > mid)
Update(rrson);
else
{
Update(llson);
Update(rrson);
}
PushDown(rt);
}
ll Query(int rt, int l, int r, int x, int y)
{
if(l >= x && r <= y)
return tree[rt];
int mid = (l + r) >> 1;
ll ans = 0;
if(mid >= y)
ans += Query(llson);
else if(x > mid)
ans += Query(rrson);
else
{
ans += Query(llson);
ans += Query(rrson);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
init();
int n, m;
cin >> n >> m;
BuildTree(1, 1, n);
for(int k = 0, s, L, R; k < m; k++)
{
cin >> s >> L >> R;
if(s == 1)
Update(1, 1, n, L, R);
else
cout << Query(1, 1, n, L, R) << endl;
}
}