直接维护个二进制数即可。
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define mp make_pair
#define fir first
#define sec second
#define pb push_back
#define gc getchar()
#define lint long long
#define mod 19961993
#define N 1000010
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
using namespace std;
typedef pair<int,int> pii;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline int fast_pow(int x,int k,int ans=1)
{ for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
int ans,p[N],np[N],mnv[N],ps[300],yx[70],c;lint bs;
inline int prelude(int n)
{
for(int i=2;i<=n;i++)
{
if(!np[i]) p[c++]=i,mnv[i]=i;
for(int j=0;j<c&&p[j]<=n/i;j++)
{ int x=p[j]*i;np[x]=1,mnv[x]=p[j];if(i%p[j]==0) break; }
}
for(int i=0;i<60;i++) yx[i]=(p[i]-1ll)*fast_pow(p[i],mod-2)%mod,ps[p[i]]=i;
return 0;
}
struct segment{
int l,r,pd;lint bs;
segment *ch[2];
}*rt;
inline int push_up(segment* &rt)
{ return rt->pd=(lint)rt->ch[0]->pd*rt->ch[1]->pd%mod,rt->bs=rt->ch[0]->bs|rt->ch[1]->bs,0; }
int build(segment* &rt,int l,int r)
{
rt=new segment,rt->l=l,rt->r=r;int mid=(l+r)>>1;
if(l==r) return rt->bs=1ll<<ps[3],rt->pd=3;
build(rt->ch[0],l,mid),build(rt->ch[1],mid+1,r);
return push_up(rt);
}
int update(segment* &rt,int p,int v)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(l==r)
{
rt->pd=v,rt->bs=0;
while(v>1) rt->bs|=(1ll<<ps[mnv[v]]),v/=mnv[v];
return 0;
}
return update(rt->ch[p>mid],p,v),push_up(rt);
}
int query(segment* &rt,int s,int t)
{
int l=rt->l,r=rt->r,mid=(l+r)>>1;
if(s<=l&&r<=t) return ans=(lint)ans*rt->pd%mod,bs|=rt->bs,0;
if(s<=mid) query(rt->ch[0],s,t);if(mid<t) query(rt->ch[1],s,t);
return 0;
}
int main()
{
int n=100000,m=inn();
prelude(1000000),build(rt,1,n);
for(int opt,l,r,x,v;m;m--)
if(!(opt=inn()))
{
l=inn(),r=inn(),ans=1,bs=0,query(rt,l,r);
for(int i=0;i<60;i++) if((bs>>i)&1ll) ans=(lint)ans*yx[i]%mod;
printf("%d\n",ans);
}
else x=inn(),v=inn(),update(rt,x,v);
return 0;
}
``