【清华集训2014】uoj #38 奇数国 - 线段树

直接维护个二进制数即可。

#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;
}
``

你可能感兴趣的:(线段树)