bzoj 4026 dC Loves Number Theory(主席树)

题目链接:bzoj 4026 dC Loves Number Theory

题意:

给你n个数,有q个询问,每次问你一个区间乘积的欧拉函数。

强制在线。

题解:

由欧拉函数性质:

euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数

可知,我们需要维护一个区间的数的乘积的不同的质因数。

这里我就直接维护1-1/pi了,然后主席树维护一下这个东西,维护方式和用主席树维护区间不同的数都多少个类似。

然后对于每个数分解质因数,这里要预处理好。

用vector会T,最好用链表。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4   
 5 const int N=1e6+1000,P=1e6+777; 
 6 struct node{int l,r,pct;node(){pct=1;}}T[N*10];
 7 int n,q,cnt,x,l,r,f[N],root[N];
 8 int g[N],v[N*3],nxt[N*3],ed;
 9 int ans,pct[N],inv[N]={0,1};
10 bool vis[N];
11   
12 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
13   
14 void update(int pos,int val,int l,int r,int &x,int y)
15 {
16     T[x=++cnt]=T[y],T[x].pct=1ll*T[x].pct*val%P;
17     if(l==r)return;
18     int mid=l+r>>1;
19     if(pos<=mid)update(pos,val,l,mid,T[x].l,T[y].l);
20     else update(pos,val,mid+1,r,T[x].r,T[y].r);
21 }
22   
23 int query(int rt,int L,int R,int l,int r)
24 {
25     if(L<=l&&r<=R)return T[rt].pct;
26     int mid=l+r>>1;int an=1;
27     if(L<=mid)an=1ll*an*query(T[rt].l,L,R,l,mid)%P;
28     if(R>mid)an=1ll*an*query(T[rt].r,L,R,mid+1,r)%P;
29     return an;
30 }
31   
32 int main(){
33     F(i,2,N)
34     {
35         if(vis[i])continue;
36         for(int j=i;j<N;j+=i)
37             vis[j]=1,adg(j,i);
38     }
39     F(i,2,N-1)inv[i]=1ll*inv[P%i]*(P-P/i)%P;
40     pct[0]=1,scanf("%d%d",&n,&q);
41     F(i,1,n)
42     {
43         scanf("%d",&x);
44         pct[i]=x,pct[i]=1ll*pct[i]*pct[i-1]%P;
45         int val=1;
46         for(int j=g[x];j;j=nxt[j])
47         {
48             int it=v[j];
49             val=1ll*val*(it-1)%P*inv[it]%P;
50         }
51         update(i,val,1,n,root[i],root[i-1]);
52         for(int j=g[x];j;j=nxt[j])
53         {
54             int it=v[j];
55             if(f[it])
56             {
57                 val=1ll*inv[it-1]*it%P;
58                 update(f[it],val,1,n,root[i],root[i]);
59             }
60             f[it]=i;
61         }
62     }
63     F(i,1,q)
64     {
65         scanf("%d%d",&l,&r);
66         l^=ans,r^=ans;
67         ans=query(root[r],l,r,1,n);
68         ans=1ll*ans*pct[r]%P*inv[pct[l-1]]%P;
69         printf("%d\n",ans);
70     }
71     return 0;
72 }
View Code

 

posted @ 2017-07-13 15:02  bin_gege  阅读(123)  评论(0编辑  收藏  举报