#38. 【清华集训2014】奇数国|线段树|欧拉函数

来源:互联网 发布:背身护球 知乎 编辑:程序博客网 时间:2024/06/06 19:09

最后一个点一直T。。。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define LL long longconst int MAXN=100010;const int MO=19961993;const int N=100000;struct H{LL cnt;int x;}seg[MAXN*4],ans;int n,prime[61]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281};void Ins(int now,int l,int r,int loc,int x){if(l==r){seg[now].x=x;seg[now].cnt=0;for(int i=1;i<=60;i++){seg[now].cnt<<=1;if(x%prime[i]==0){seg[now].cnt|=1;while(x%prime[i]==0) x/=prime[i];}}return ;}int mid=(l+r)/2;if(loc<=mid) Ins(now*2,l,mid,loc,x);else Ins(now*2+1,mid+1,r,loc,x);seg[now].cnt=seg[now*2].cnt|seg[now*2+1].cnt;seg[now].x=(LL)seg[now*2].x*seg[now*2+1].x%MO;}void Q(int now,int l,int r,int s,int t){if(s<=l && r<=t){ans.x=(LL)ans.x*seg[now].x%MO;ans.cnt|=seg[now].cnt;return ;}int mid=(l+r)/2;if(s<=mid) Q(now*2,l,mid,s,t);if(mid+1<=t) Q(now*2+1,mid+1,r,s,t);}int F(int x,int p){if(p==0) return 1;int t=F(x,p/2);t=(LL)t*t%MO;if(p&1) t=(LL)t*x%MO;return t;}void Build(int now,int l,int r){if(l==r){seg[now].cnt=288230376151711744ll;seg[now].x=3;return ;}int mid=(l+r)/2;Build(now*2,l,mid);Build(now*2+1,mid+1,r);seg[now].cnt=seg[now*2].cnt|seg[now*2+1].cnt;seg[now].x=(LL)seg[now*2].x*seg[now*2+1].x%MO;}int main(){Build(1,1,N);cin >>n;int x,y,opt;for(int i=1;i<=n;i++){scanf("%d %d %d",&opt,&x,&y);if(opt==0){ans.x=1;Q(1,1,N,x,y);for(int i=60;i>=1;i--){if(ans.cnt&1)ans.x=(LL)ans.x*F(prime[i],MO-2)%MO*(prime[i]-1)%MO;ans.cnt>>=1;}printf("%d\n",ans.x);}elseIns(1,1,N,x,y);}return 0;}


0 0