• BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)


    题目大意:给你一个序列,求出指定区间的varphi (a[i])(l<=i<=r) mod 1000777 的值

    还复习了欧拉函数以及线性筛逆元

    考虑欧拉函数的的性质,varphi (prod a[i])(l<=i<=r),等价于prod a[i]*prod p[j]-1/p[j] (p[j]是区间内所有出现过的质数)

    那么考虑找出区间内所有出现过的质数,这思路和HH的项链是不是很像??

    由于此题强制在线,所以把树状数组替换成了主席树而已

    原来我以前写的主席树一直都是错的......还好推出了我原来错误代码的反例

    在继承上一个树的信息时,注意不要破坏现在的树

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define ll long long 
      5 #define il inline
      6 #define N 50010
      7 #define maxn 1000000
      8 #define mod 1000777
      9 using namespace std;
     10  
     11 int n,q,ctp,tot;
     12 int root[N];
     13 int pr[maxn+100],use[maxn+100],lst[maxn+100];
     14 ll a[N],inv[mod+100],nxt[maxn+100];
     15 struct Seg{ll sum;int ls,rs;}seg[N*60]; //re
     16 void prime_inv()
     17 {
     18     for(int i=2;i<=maxn;i++)
     19     {
     20         if(!use[i])
     21             pr[++ctp]=i,nxt[i]=i;
     22         for(int j=1;j<=ctp&&i*pr[j]<=maxn;j++){
     23             use[i*pr[j]]=1,nxt[i*pr[j]]=pr[j];
     24             if(i%pr[j]==0) break;
     25         }
     26     }
     27     inv[0]=inv[1]=1;
     28     for(ll i=2;i<mod;i++)
     29         inv[i]=(mod-mod/i)*inv[mod%i]%mod;
     30 }
     31 ll gc()
     32 {
     33     ll ret=0,fh=1;char p=getchar();
     34     while(p<'0'||p>'9') {if(p=='-')fh=-1;p=getchar();}
     35     while(p>='0'&&p<='9') {ret=(ret<<3)+(ret<<1)+p-'0';p=getchar();}
     36     return ret*fh;
     37 }
     38 il void pushup(int rt){seg[rt].sum=(seg[seg[rt].ls].sum*seg[seg[rt].rs].sum)%mod;}
     39 void build(int l,int r,int rt)
     40 {
     41     seg[rt].sum=1;
     42     if(l==r)return;
     43     int mid=(l+r)>>1;
     44     seg[rt].ls=++tot,build(l,mid,tot);
     45     seg[rt].rs=++tot,build(mid+1,r,tot);
     46 }
     47 void update(int x,int l,int r,int rt1,int rt2,ll w)
     48 {
     49     if(l==r) {seg[rt2].sum=(seg[rt2].sum*w)%mod;return;}
     50     int mid=(l+r)>>1;
     51     if(x<=mid)
     52     {
     53         if(!seg[rt2].ls||seg[rt1].ls==seg[rt2].ls){
     54             seg[rt2].ls=++tot,seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum;
     55         if(!seg[rt2].rs) 
     56             seg[rt2].rs=seg[rt1].rs;
     57         } 
     58         update(x,l,mid,seg[rt1].ls,seg[rt2].ls,w);
     59     }else{
     60         if(!seg[rt2].rs||seg[rt1].rs==seg[rt2].rs){
     61             seg[rt2].rs=++tot,seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum;
     62         if(!seg[rt2].ls)
     63             seg[rt2].ls=seg[rt1].ls;
     64         }
     65         update(x,mid+1,r,seg[rt1].rs,seg[rt2].rs,w);
     66     }
     67     pushup(rt2);
     68 }
     69 ll query(int L,int R,int l,int r,int rt)
     70 {
     71     if(L<=l&&r<=R) return seg[rt].sum;
     72     int mid=(l+r)>>1;ll ans=1;
     73     if(L<=mid) ans*=query(L,R,l,mid,seg[rt].ls),ans%=mod;
     74     if(R>mid) ans*=query(L,R,mid+1,r,seg[rt].rs),ans%=mod;
     75     return ans;
     76 }
     77  
     78 int main()
     79 {
     80     //freopen("a.in","r",stdin);
     81     //freopen("a.out","w",stdout);
     82     scanf("%d%d",&n,&q);
     83     for(int i=1;i<=n;i++) a[i]=gc();
     84     prime_inv();
     85     root[0]=++tot;
     86     build(1,n,1);
     87     ll x,p,w;
     88     for(int i=1;i<=n;i++)
     89     {
     90         x=a[i],w=a[i],root[i]=++tot;
     91         while(x!=1){
     92             p=nxt[x];
     93             if(lst[p])
     94                 update(lst[p],1,n,root[i-1],root[i],(inv[p-1]*p)%mod);
     95             lst[p]=i;
     96             x/=p,w=((w*(p-(ll)1)%mod)*inv[p])%mod;
     97             while(x%p==0) x/=p;
     98         }
     99         update(i,1,n,root[i-1],root[i],w);
    100     }
    101     ll l,r,ans=0;
    102     for(int i=1;i<=q;i++)
    103     {
    104         l=gc(),r=gc();
    105         l^=ans,r^=ans;
    106         ans=query(l,r,1,n,root[r]);
    107         printf("%lld
    ",ans);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    Qt error: ‘class Ui::XXXXX‘ has no member named ‘XXXXX‘
    Visual Studio 模块计算机类型“x64”与目标计算机类型“x86”冲突
    Qt 报错:error dependent 'xxx' does not exist.
    Qt 可重入和线程安全的理解
    光学显微镜的一些技术参数
    C++ 内联函数解析(inline)
    显微镜的景深
    Windows下的Qt编译器 MinGW和MSVC的区别
    C/C++ 回调函数(Callback)& 函数指针
    C++ 回调函数详解
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697037.html
Copyright © 2020-2023  润新知