zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    Day 29 作业/服务端实现接收客户端的连接并发
    Day 28 操作系统发展/进程
    Day 27 作业(FTP)
    Day 27 subprocess模块/粘包问题以及解决/UDP协议/socketserver
    Day 26 作业
    Day 26 互联网协议/Socket套接字
    Day 22 绑定方法和非绑定方法/isinstance/issubclass/反射/魔法方法/单例模式
    Day 21 作业
    Day 21 组合/封装/property特性/多态和多态性/抽象类/鸭子类型
    day 20 作业
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7160552.html
Copyright © 2011-2022 走看看