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 liri (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
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e6;
const int MOD=1e9+7;
typedef __int64 ll;
int a[MAX],d[MAX];
ll A[MAX];
int n,m;
set<int>p;
set<int>::iterator it;
void init()//计算D[i]
{
memset(d,0,sizeof d);
d[0]=0;
for(int i=1;i<=1e6;i++)
{
for(int j=i;j<=1e6;j+=i)d[j]++;
}
}
void add(int x,int y)
{
while(x<=n)
{
A[x]+=y;
x+=x&(-x);
}
}
ll ask(int x)
{
ll ans=0;
while(x)
{
ans+=A[x];
x-=x&(-x);
}
return ans;
}
int main()
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
add(i,a[i]);
if(a[i]>2)p.insert(i);
}
while(m--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
it=p.lower_bound(x);
while(it!=p.end()&&*it<=y)
{
int pre=a[*it],nex=d[a[*it]];
add(*it,nex-pre);//更新树状数组
a[*it]=nex;//更新a[i]
if(nex<=2)p.erase(it++);//a[i]<=2,删除
else it++;
}
}
else printf("%I64d\n",ask(y)-ask(x-1));
}
return 0;
}