题解:
标程:
#include<bits/stdc++.h>
#define lc ((o) << 1)
#define rc ((o) << 1 | 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> Pair;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
int Mul[maxn << 2], Div[maxn << 2], a[maxn];
vector<int>factor[maxn], suf[maxn];
bool vis[maxn];
int prime[1010], tot;
void init(int n)//找出所有素数
{
for(int i = 2; i <= n; i++)if(!vis[i])
{
prime[++tot] = i;
for(ll j = (ll)i * i; j <= n; j += i)vis[j] = 1;
}
}
void pushdown(int o, int l, int r)//标记下放,重点
{
if(Mul[o] || Div[o])
{
if(Mul[lc] >= Div[o])Mul[lc] -= Div[o];//如果先乘后除,除把乘抵消
else Div[lc] += (Div[o] - Mul[lc]), Mul[lc] = 0;
if(Mul[rc] >= Div[o])Mul[rc] -= Div[o];
else Div[rc] += (Div[o] - Mul[rc]), Mul[rc] = 0;
Mul[lc] += Mul[o];//乘法运算正常加
Mul[rc] += Mul[o];
Mul[o] = Div[o] = 0;
}
}
void update(int o, int l, int r, int L, int R, int tree[], int op)
{
if(L <= l && R >= r)
{
if(op == 1)tree[o]++;//乘法运算正常加
else
{
if(Mul[o])Mul[o]--;//如果先乘后除,除把乘抵消
else tree[o]++;
}
return;
}
pushdown(o, l, r);
int m = (l + r) / 2;
if(L <= m)update(lc, l, m, L, R, tree, op);
if(R > m)update(rc, m + 1, r, L, R, tree, op);
}
void query(int o, int l, int r, int x, int& divnum, int& mulnum)
{
if(l == r)
{
divnum = Div[o];
mulnum = Mul[o];
return;
}
pushdown(o, l, r);
int m = (l + r) / 2;
if(x <= m)query(lc, l, m, x, divnum, mulnum);
else query(rc, m + 1, r, x, divnum, mulnum);
}
ll pow(ll a, ll b, ll m)
{
ll ans = 1;
while(b)
{
if(b & 1)ans = a * ans % m;
b >>= 1;
a = a * a % m;
}
return ans;
}
int main()
{
int n, m;
init(1000);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);int x = a[i];
for(int j = 1; j <= tot && prime[j] * prime[j] <= x; j++)
while(x % prime[j] == 0)x /= prime[j], factor[i].push_back(prime[j]);
if(x != 1)factor[i].push_back(x);//因为x>=4才能执行上面的循环
// x = a[i];
//for(int j = 0; j < factor[i].size(); j++)cout<<factor[i][j]<<" ";cout<<endl;
}
for(int i = 1; i <= m; i++)
{
int op, l, r;
scanf("%d", &op);
if(op == 1)
{
scanf("%d%d", &l, &r);
update(1, 1, n, l, r, Mul, 1);
}
else if(op == 2)
{
scanf("%d%d", &l, &r);
update(1, 1, n, l, r, Div, 2);
}
else if(op == 3)
{
scanf("%d", &l);
int divnum = 0, mulnum = 0;
query(1, 1, n, l, divnum, mulnum);
//cout<<divnum<<" "<<mulnum<<endl;
if(divnum >= factor[l].size())puts("1");
else
{
int ans = 1, tmp = factor[l][divnum];
//cout<<tmp<<endl;
for(int i = divnum; i < factor[l].size(); i++)
ans *= factor[l][i];
ans = (ll)ans * pow(tmp, mulnum, MOD) % MOD;
printf("%d\n", ans);
}
}
}
return 0;
}