分析
我们首先要知道,一个数的因子个数怎么算。若一个数为 2^7 * 3^8,那么他的因子个数就为 (7 + 1) * (8 + 1) ,72 以内只有 20 个质数,因此我们只要维护 20 个树状数组,维护每个质因数的个数。
代码
#include<bits/stdc++.h>
#define lowbit(a) ((a) & (-a))
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll pr[25] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
ll c[100007][25];
ll a[100007];
void update(ll x,ll j,ll y,ll n)
{
for(ll b=x;b<=n;b+=lowbit(b))
{
c[b][j] = (c[b][j] + y + mod) % mod;
}
}
ll getsum(ll x,ll j)
{
ll res = 0;
for(ll b=x;b>=1;b-=lowbit(b))
{
res = (res + c[b][j]) % mod;
}
return res % mod;
}
void solve()
{
ll n,m,x,y,sum;
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&x);
a[i] = x;
for(ll j=1;j<=20;j++)
{
sum = 0;
ll t = x;
while(t % pr[j] == 0)
{
sum++;
t /= pr[j];
}
update(i, j, sum, n);
}
}
ll op;
while(m--)
{
scanf("%lld%lld%lld",&op,&x,&y);
if(op == 1)
{
ll t = a[x], cnt = 0;
for(ll j=1;j<=20;j++)
{
cnt = 0;
while(t % pr[j] == 0)
{
cnt++;
t /= pr[j];
}
update(x, j, -cnt, n);
}
for(ll j=1;j<=20;j++)
{
sum = 0;
ll t = y;
while(t % pr[j] == 0)
{
sum++;
t /= pr[j];
}
update(x, j, sum, n);
}
a[x] = y;
}
else if(op == 2)
{
ll tmp1, tmp2;
ll ans = 1;
for(ll i=1;i<=20;i++)
{
tmp1 = getsum(y, i);
tmp2 = getsum(x - 1, i);
ans = ans * ((tmp1 + mod - tmp2 + 1) % mod) % mod;
//cout<<pr[i]<<"---"<<tmp2<<" "<<tmp1<<endl;
}
printf("%lld\n",ans);
}
}
}
int main()
{
int T = 1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}