题面:
题解:
线段树上每个节点维护该节点上的数唯一分解之后的 p 和 e
因为除***使其不同的质因子减少,乘法不会。
所以遇到有可能使质因子减少的情况就一直更改到底即可。
因为质因子总个数不会超过20个,所以,遇到质因子减少的情况就往下更改,每个点被更改的次数的期望不超过20次
时间复杂度O(n * (logn + 20))
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
#define ui unsigned int
#define ll long long
#define llu unsigned ll
#define ld long double
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
#define len(x) (t[(x)].r-t[(x)].l+1)
#define tmid ((l+r)>>1)
#define forhead(x) for(int i=head[(x)];i;i=nt[i])
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define one(n) for(int i=1;i<=(n);i++)
#define rone(n) for(int i=(n);i>=1;i--)
#define fone(i,x,n) for(int i=(x);i<=(n);i++)
#define frone(i,n,x) for(int i=(n);i>=(x);i--)
#define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))
#define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))
#define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)
#define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)
#define cls(a) memset(a,0,sizeof(a))
#define cls1(a) memset(a,-1,sizeof(a))
#define clsmax(a) memset(a,0x3f,sizeof(a))
#define clsmin(a) memset(a,0x80,sizeof(a))
#define cln(a,num) memset(a,0,sizeof(a[0])*num)
#define cln1(a,num) memset(a,-1,sizeof(a[0])*num)
#define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)
#define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)
#define sc(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define scl(x) scanf("%lld",&x)
#define scl2(x,y) scanf("%lld%lld",&x,&y)
#define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define scf(x) scanf("%lf",&x)
#define scf2(x,y) scanf("%lf%lf",&x,&y)
#define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
#define scs(x) scanf("%s",x+1)
#define scs0(x) scanf("%s",x)
#define scline(x) scanf("%[^\n]%*c",x+1)
#define scline0(x) scanf("%[^\n]%*c",x)
#define pcc(x) putchar(x)
#define pc(x) printf("%d\n",x)
#define pc2(x,y) printf("%d %d\n",x,y)
#define pc3(x,y,z) printf("%d %d %d\n",x,y,z)
#define pck(x) printf("%d ",x)
#define pcl(x) printf("%lld\n",x)
#define pcl2(x,y) printf("%lld %lld\n",x,y)
#define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)
#define pclk(x) printf("%lld ",x)
#define pcf2(x) printf("%.2f\n",x)
#define pcf6(x) printf("%.6f\n",x)
#define pcf8(x) printf("%.8f\n",x)
#define pcs(x) printf("%s\n",x+1)
#define pcs0(x) printf("%s\n",x)
#define pcline(x) printf("%d**********\n",x)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int maxm=100100;
const int up=100000;
const int hp=13331;
const int maxn=100100;
//2*3*5*7*11*13*17*19=9699690
ll mypow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
struct node
{
int l,r;
int p[10],e[10];
int now,laz;
}t[maxn<<2];
void build(int l,int r,int cnt)
{
t[cnt].l=l,t[cnt].r=r;
t[cnt].laz=0;
if(l==r)
{
cls(t[cnt].p),cls(t[cnt].e);
int x;
sc(x);
int tot=0;
for(int i=2;i*i<=x;i++)
{
if(x%i) continue;
t[cnt].p[++tot]=i;
while(x%i==0)
t[cnt].e[tot]++,x/=i;
}
if(x>1) t[cnt].p[++tot]=x,t[cnt].e[tot]=1;
t[cnt].p[++tot]=1,t[cnt].e[tot]=1;
t[cnt].now=1;
return ;
}
build(l,tmid,lc);
build(tmid+1,r,rc);
}
void check(int cnt)
{
if(t[cnt].laz>=0) return ;
if(t[cnt].l==t[cnt].r)
{
t[cnt].e[t[cnt].now]+=t[cnt].laz;
t[cnt].laz=0;
while(t[cnt].e[t[cnt].now]<=0&&t[cnt].p[t[cnt].now]>1)
{
t[cnt].e[t[cnt].now+1]+=t[cnt].e[t[cnt].now];
t[cnt].now++;
}
return ;
}
t[lc].laz+=t[cnt].laz;
t[rc].laz+=t[cnt].laz;
t[cnt].laz=0;
check(lc);
check(rc);
}
void pushdown(int cnt)
{
if(t[cnt].laz!=0)
{
t[lc].laz+=t[cnt].laz;
t[rc].laz+=t[cnt].laz;
t[cnt].laz=0;
}
}
void change(int l,int r,int cnt,int val)
{
if(l<=t[cnt].l&&t[cnt].r<=r)
{
t[cnt].laz+=val;
check(cnt);
return ;
}
pushdown(cnt);
if(l<=t[lc].r) change(l,r,lc,val);
if(r>=t[rc].l) change(l,r,rc,val);
return ;
}
ll ask(int pos,int cnt)
{
if(t[cnt].l==t[cnt].r)
{
t[cnt].e[t[cnt].now]+=t[cnt].laz;
t[cnt].laz=0;
ll x=1;
for(int i=t[cnt].now;t[cnt].p[i]!=1;i++)
x=(x*mypow(t[cnt].p[i],t[cnt].e[i]))%mod;
return x;
}
pushdown(cnt);
if(pos<=t[lc].r) return ask(pos,lc);
else return ask(pos,rc);
}
int main(void)
{
int n,m;
sc2(n,m);
build(1,n,1);
int k,x,y;
one(m)
{
sc(k);
if(k==1)
{
sc2(x,y);
change(x,y,1,1);
}
else if(k==2)
{
sc2(x,y);
change(x,y,1,-1);
}
else
{
sc(x);
printf("%lld\n",ask(x,1));
}
}
return 0;
}