zoukankan      html  css  js  c++  java
  • Bzoj3481 DZY Loves Math III

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 310  Solved: 65

    Description

    Input

    Output

    Sample Input

    3
    1
    2
    3
    2
    4
    2

    Sample Output

    6

    HINT


    1<=N<=10,0<=Qi<=10^18,1<=Pi<=10^18,P>=2


    本题仅四组数据。

    Source

    数学问题 欧拉函数 Miller-Rabin Pollard-rho

    花了一整晚来怼这道题……在long long的领域遇到了许多问题。

    假设我们有充足的时间枚举每一个x,那么在x确定的情况下,原式变成了一个模方程。
    根据裴蜀定理,我们知道只有当$ gcd(x,P)|Q $ 的情况下方程有 $ gcd(x,P) $ 个解。
    现在我们可以愉快地枚举每一个gcd,那么答案就是:
    $$ans=sum_{d|P,d|Q} d * sum_{x}[gcd(x,frac{P}{d})==1]$$
    后面那个sum显然是欧拉函数
    那么$$ ans=sum_{d|P,d|Q} d · varphi(frac{P}{d}) $$
    分(an)析(zhao)一(tao)波(lu),发现这是一个积性函数,所以我们可以分别考虑每个质因子的贡献,再把它们累乘起来。
    我们现在考虑一个质因子p,它在P中有$q$个,在Q中有$q'$个:
    它对答案的贡献是
    $$ sum_{i=0}^{q'} p^i * varphi(p^{q-i})$$
    我们知道
    $$varphi(p^{q})=p^{q}·frac{p-1}{p}$$
    所以上面的sum可以化成:
    $$p^{q-1}·(p-1)·(q'+1)$$
    但是有一个特殊情况,当i=q的时候,$varphi(1)=1$,不能表示成$frac{p-1}{p}$的形式,而我们却把它用这种形式算进去了。
    也就是说我们把一个$p^q$ 的贡献算成了 $(p-1)p^{q-1}$,特判一下消除即可。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<map>
      7 #define LL long long
      8 using namespace std;
      9 const int mxn=100010;
     10 LL read(){
     11     LL x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
     14     return x*f;
     15 }
     16 LL Rand(LL n){return (((LL)rand()<<31)|rand())%(n-1)+1;}
     17 //
     18 map<LL,int>primap;
     19 LL pri[mxn*10];int cnt=0;
     20 bool vis[mxn];
     21 void init(){
     22     int mxn=200;
     23     for(int i=2;i<mxn;i++){
     24         if(!vis[i]){
     25             pri[++cnt]=i;
     26             primap[i]=cnt;
     27         }
     28         for(int j=1;j<=cnt && pri[j]*i<mxn;j++){
     29             vis[pri[j]*i]=1;
     30             if(i%pri[j]==0)break;
     31         }
     32     }
     33     return;
     34 }
     35 //
     36 LL mul(LL x,LL k,LL P)
     37 {
     38     LL res=0;
     39     while(k){
     40         if(k&1)res=(res+x)%P;
     41         x=(x+x)%P;
     42         k>>=1;
     43     }
     44     return res;
     45 }
     46 /*
     47 LL mul(LL a,LL b,LL P){
     48     LL d=(long double)a/P*b+1e-8;
     49     
     50     a=a*b-d*P;
     51     a=(a<0)?a+P:a;
     52     printf("%lld 
    ",a);
     53     return a;
     54 }*/
     55 LL ksm(LL a,LL k,LL P){
     56     LL res=1;
     57     while(k){
     58         if(k&1)res=mul(res,a,P);
     59         a=mul(a,a,P);
     60         k>>=1;
     61     }
     62     return res;
     63 }
     64 ///
     65 bool check(LL a,LL n,LL r,LL s){
     66     LL res=ksm(a,r,n);LL b=res;
     67     for(int i=1;i<=s;i++){
     68         res=mul(res,res,n);
     69         if(res==1 && b!=1 && b!=n-1)return 1;
     70         b=res;
     71     }
     72     return (res!=1);
     73 }
     74 bool MR(LL n){//素数测试 
     75     if(n<=1)return 0;
     76     if(n==2)return 1;
     77     if(~n&1)return 0;
     78     LL r=n-1,s=0;
     79     while(!(r&1))r>>=1,s++;
     80     for(int i=1;i<=10;i++)
     81         if(check(Rand(n),n,r,s))return 0;
     82     return 1;
     83 }
     84 ///
     85 LL p[mxn],q[mxn];
     86 void addpri_P(LL x){
     87     if(primap.count(x)){
     88         ++p[primap[x]];return;
     89     }
     90     pri[++cnt]=x;
     91     primap[x]=cnt;
     92     p[cnt]=1;
     93     return;
     94 }
     95 void addpri_Q(LL x){
     96     if(primap.count(x)){
     97         int t=primap[x];
     98         if(q[t]<p[t])++q[t];
     99     }
    100     return;
    101 }
    102 LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    103 LL Rho(LL n,LL c){
    104     if(n<0)while(1);
    105     LL k=2,x=Rand(n),y=x,p=1;
    106     for(LL i=1;p==1;i++){
    107         x=(mul(x,x,n)+c)%n;
    108         p=(y>x)?(y-x):(x-y);
    109         p=gcd(n,p);
    110         if(i==k)y=x,k<<=1;
    111     }
    112     return p;
    113 }
    114 void solve(LL x,bool flag){//分解质因数 
    115     if(x==1)return;
    116     if(MR(x)){
    117         if(!flag)addpri_P(x);//P
    118         else addpri_Q(x);//Q
    119         return;
    120     }
    121     LL t=x;
    122     while(t==x)t=Rho(x,Rand(x));
    123     solve(t,flag);
    124     solve(x/t,flag);
    125     return;
    126 }
    127 //
    128 const int mod=1e9+7;
    129 int n;
    130 LL P[50],Q[50];
    131 void Calc(){
    132     LL ans=1;
    133     for(int i=1;i<=cnt;i++){
    134         if(!p[i])continue;
    135         LL R=mul((q[i]+1),(pri[i]-1),mod);
    136         if(p[i]==q[i])R++;
    137         R=mul(R,ksm(pri[i],p[i]-1,mod),mod);
    138         ans=mul(ans,R,mod);
    139     }
    140     printf("%lld
    ",ans);
    141     return;
    142 }
    143 int main(){
    144     srand(19260817);
    145     init();
    146     int i,j;
    147     n=read();
    148     for(i=1;i<=n;i++){
    149         P[i]=read();
    150         solve(P[i],0);
    151     }
    152     for(i=1;i<=n;i++){
    153         Q[i]=read();
    154         if(!Q[i]){//特判0 
    155             for(j=1;j<=cnt;j++)q[j]=p[j];
    156             break;
    157         }
    158         else solve(Q[i],1);
    159     }
    160     Calc();
    161     return 0;
    162 }
  • 相关阅读:
    第一周作业
    第0次作业
    IOS和Android解析newDate()不兼容问题
    行 1: <%@ Application Codebehind="Global.asax.cs" Inherits="FuceFP.Web.Global" Language="C#" %>
    The edge module has not been pre-compiled for node.js version v6.11.2. You must build a custom version of edge.node. Please refer to https://github.com/tjanczuk/edge for building instructions.
    无法确定条件表达式的类型,因为Datetime和<null>之间没有隐式转换
    VS Android Cordova 环境搭建 Java SDK/AVD Manager 闪退
    机器学习系列(3) 决策树
    python系列(2) 函数
    MYSQL系列(4) 窗口函数解决连续几天登录的问题
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6965017.html
Copyright © 2011-2022 走看看