zoukankan      html  css  js  c++  java
  • 奇数国

      大半夜罗了奇怪的做法,发现M啦QAQ,内心死亡,然而第二天早上写完另一种发现交的代码是nn=4,内心死亡again

      首先从题意分析就是,线段树上罗,然后求欧拉函数

      两种做法的区别在于求的公式不同

      第一种是,phi(x)=sigma(pn-1)pn^(an-1),其中pn为对x分解质因数

      这种做法需要记录每个因数的个数,所以奇慢

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define lson rt<<1,l,mid
     5 #define rson rt<<1|1,mid+1,r
     6 #define maxn 100005
     7 #define mod 19961993
     8 typedef long long i64;
     9 struct node{
    10     int v[61];
    11     void clear(){memset(v,0,sizeof(v));}
    12     node operator+(const node &t)const{
    13         node tmp;
    14         tmp.v[0]=0;//
    15         for(int i=1;i<=60;i++)
    16             tmp.v[i]=v[i]+t.v[i];
    17         return tmp;
    18     }
    19 
    20 }tree[maxn<<2],tmp;
    21 i64 prime[]={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};
    22 int nn=100000;
    23 int read(){
    24     int haha=0;
    25     char ch=0;
    26     while(!isdigit(ch))ch=getchar();
    27     while(isdigit(ch)){
    28         haha=haha*10+ch-'0';
    29         ch=getchar();
    30     }
    31     return haha;
    32 }
    33 node div(int x){
    34     node t;
    35     t.v[0]=0;//
    36     for(int i=1;i<=60;i++){
    37         t.v[i]=0;
    38         while(x&&x%prime[i]==0)
    39             t.v[i]++,x/=prime[i];
    40     }
    41     return t;
    42 }
    43 void update(int rt,int l,int r,int pos,int x){
    44     if(l==r){
    45         tree[rt]=div(x);
    46         return;
    47     }
    48     int mid=(l+r)>>1;
    49     if(pos<=mid)update(lson,pos,x);
    50     else update(rson,pos,x);
    51     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    52 }
    53 void query(int rt,int l,int r,int ql,int qr){
    54     if(ql<=l&&qr>=r){
    55         tmp=tmp+tree[rt];
    56         return;
    57     }
    58     int mid=(l+r)>>1;
    59     if(ql<=mid)query(lson,ql,qr);
    60     if(qr>mid)query(rson,ql,qr);
    61 }
    62 i64 qp(i64 bs,int x){
    63     i64 ans=1;
    64     while(x){
    65         if(x&1)ans=(ans*bs)%mod;
    66         bs=(bs*bs)%mod;
    67         x>>=1;
    68     }
    69     return ans;
    70 }
    71 int main(){
    72     for(int i=1;i<=nn;i++)
    73         update(1,1,nn,i,3);
    74     int n,op,a,b;
    75     n=read();
    76     for(int i=1;i<=n;i++){
    77         op=read(),a=read(),b=read();
    78         if(!op){
    79             tmp.clear();
    80             query(1,1,nn,a,b);
    81             i64 ans=1LL;
    82             for(int j=1;j<=60;j++)
    83                 if(tmp.v[j])
    84                     ans=(ans*((prime[j]-1)*qp(prime[j],tmp.v[j]-1))%mod)%mod;
    85             printf("%lld
    ",ans);//
    86         }
    87         else update(1,1,nn,a,b);
    88     }
    89     return 0;
    90 }
    View Code

      

      第二种是phi(x)=x*(p1-1)/p1*(p2-1)/p2*...*(pn-1)/pn

      这玩意只需要知道x的因数有哪些,可以压到一个long long里,因为有除法,所以会用到乘法逆元

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long i64;
     5 #define lson rt<<1,l,mid
     6 #define rson rt<<1|1,mid+1,r
     7 #define mod 19961993
     8 #define maxn 100005
     9 const int nn=100000;
    10 i64 prime[]={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};
    11 i64 am,ap,pri[maxn<<2],mul[maxn<<2],ni[60];
    12 
    13 int read(){
    14     int tmp=0;
    15     char ch=0;
    16     while(!isdigit(ch))ch=getchar();
    17     while(isdigit(ch)){
    18         tmp=tmp*10+ch-'0';
    19         ch=getchar();
    20     }
    21     return tmp;
    22 }
    23 i64 div(int x){
    24     i64 haha=0;
    25     for(int i=0;i<60;i++)
    26         if(x%prime[i]==0)haha|=(1LL<<i);
    27     return haha;
    28 }
    29 void update(int rt,int l,int r,int pos,int x){
    30     if(l==r){
    31         mul[rt]=x%mod;
    32         pri[rt]=div(x);
    33         return;
    34     }
    35     int mid=(l+r)>>1;
    36     if(pos<=mid)update(lson,pos,x);
    37     else update(rson,pos,x);
    38     mul[rt]=(mul[rt<<1]*mul[rt<<1|1])%mod;
    39     pri[rt]=pri[rt<<1]|pri[rt<<1|1];
    40 }
    41 void query(int rt,int l,int r,int ql,int qr){
    42     if(ql<=l&&qr>=r){
    43         am=(am*mul[rt])%mod;
    44         ap|=pri[rt];
    45         return;
    46     }
    47     int mid=(l+r)>>1;
    48     if(ql<=mid)query(lson,ql,qr);
    49     if(qr>mid)query(rson,ql,qr);
    50 }
    51 i64 qp(i64 bs,int x){
    52     i64 sum=1LL;
    53     while(x){
    54         if(x&1)sum=(sum*bs)%mod;
    55         bs=(bs*bs)%mod;
    56         x>>=1;
    57     }
    58     return sum;
    59 }
    60 int main(){
    61     for(int i=0;i<60;i++)
    62         ni[i]=qp(prime[i],mod-2);
    63     for(int i=1;i<=nn;i++)
    64         update(1,1,nn,i,3);
    65     int n,op,a,b;
    66     n=read();
    67     for(int i=1;i<=n;i++){
    68         op=read(),a=read(),b=read();
    69         if(!op){
    70             am=1LL,ap=0;
    71             query(1,1,nn,a,b);
    72             for(int j=0;j<60;j++)
    73                 if(ap&(1LL<<j))am=(am*((prime[j]-1)*ni[j])%mod)%mod;
    74             printf("%lld
    ",am);
    75         }
    76         else update(1,1,nn,a,b);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    栈的压入,弹出序列
    json格式实现批量删除
    ExtJS pagingtoolbar的使用
    Unknown initial character set index '45' received from server. Initial client ch
    事务的原子性
    整合Struts2.2+Spring3.0
    两种方法判断输入是否整数
    使用三种不同循环结构对1+2+3+...+100 求和
    使用循环的方式输出对应图形
    系统任务栏图标透明且无法打开解决办法 for Windows
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5085193.html
Copyright © 2011-2022 走看看