zoukankan      html  css  js  c++  java
  • HDU5780 gcd 欧拉函数

    http://acm.hdu.edu.cn/showproblem.php?pid=5780

    BC #85 1005

    思路:

    首先原式化简:x​^gcd(a,b)​​1

    也就是求n内,(公约数是i的对数)*x^i-1的和,其中i为n内的两两最大公约数。那么问题可以转化成先预处理出i,再求和,注意O(n*300)=1,正常情况会卡常数。必须还要优化

    由于 ans=∑s[d](x^d​​1),记s[d]=最大公约数为d的对数

    我们注意到求s[d] or (公约数是i的对数),也就是求n/i以内互质数的对数,显然用欧拉来做

    s[d]=2*(phi[1]+phi[2]+...+phi[n/d])-1

    注意到:d不同,但是n/d一样,也就是s[d]可能有多个相同,比如 10/6 10/7 10/8 10/9 10/10,所以求s[d]相同的项,我们可以用等比公式求和(快速幂+逆元 新知识)

    所以我们只要找到每一段s[d]就可以 即 j=n/(n/i),j为最后一个相同s[d]的下标

     1 // #pragma comment(linker, "/STACK:102c000000,102c000000")
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <sstream>
     6 #include <string>
     7 #include <algorithm>
     8 #include <list>
     9 #include <map>
    10 #include <vector>
    11 #include <queue>
    12 #include <stack>
    13 #include <cmath>
    14 #include <cstdlib>
    15 // #include <conio.h>
    16 using namespace std;
    17 #define pi acos(-1.0)
    18 const int N = 1e6+10;
    19 const int MOD = 1e9+7;
    20 #define inf 0x7fffffff
    21 typedef long long  LL;
    22 
    23 void fre() { freopen("in.txt","r",stdin);}
    24 inline int read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;}
    25 
    26 LL pow_m(LL x,LL n) 
    27 {
    28     LL res=1;
    29     while(n>0)
    30     {
    31         if(n & 1)
    32             res=(res*x)%MOD;
    33         x=(x*x)%MOD;
    34         n >>= 1;
    35     }
    36     return res;
    37 }
    38 
    39 int prime[N],sphi[N];
    40 int inv[N];
    41 void e_fun(){
    42     sphi[1]=1;
    43     for(int i=2;i<=N;i++){
    44         if(!sphi[i]){
    45             prime[++prime[0]]=i;
    46             sphi[i]=i-1;
    47         }
    48         for(int j=1;j<=prime[0]&&i*prime[j]<=N;j++){
    49             if(i%prime[j]) sphi[i*prime[j]]=sphi[i]*(prime[j]-1);
    50             else sphi[i*prime[j]]=sphi[i]*prime[j];
    51         }
    52     }
    53     for(int i=1;i<=N;i++) sphi[i]=(sphi[i-1]+sphi[i])%MOD;
    54     
    55     //打表求逆元 
    56     // inv[1] = inv[0] = 1;
    57     // for(int i = 2;i < N;i++)
    58     // inv[i] = inv[MOD%i]*(MOD-MOD/i)%MOD;
    59 }
    60 
    61 
    62 void ex_gcd(LL a,LL b,LL &d,LL &x,LL &y) {
    63     if (!b) {
    64         d = a;
    65         x = 1;
    66         y = 0;
    67     }
    68     else {
    69         ex_gcd(b, a%b, d, y, x);
    70         y -= x*(a/b);
    71     }
    72     // return x;
    73 }
    74 
    75 LL sn(LL q,LL n){
    76     if(q==1) return n;
    77     LL x,y,d;
    78     ex_gcd(q-1,MOD,d,x,y);
    79     return (pow_m(q,n)-1)*((x+MOD)%MOD)%MOD;
    80 }
    81 
    82 int main(){
    83     e_fun();
    84     int T;
    85     T=read();
    86     while(T--){
    87         int x,n;
    88         x=read(),n=read();
    89         LL ans=0;
    90         for(int i=1,j;i<=n;i=j+1){
    91             j=n/(n/i);
    92             LL sd=2*sphi[n/i]-1;
    93             ans=(ans + sd*(pow_m(x,i)*sn(x,j-i+1)%MOD -(j-i+1))%MOD) % MOD;
    94         }
    95         printf("%I64d
    ",ans);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    垃圾回收机制_合集
    线程_同步应用
    动态给类的实例对象 或 类 添加属性
    【Python】画一个心形
    【JS】网站运行时间
    【Python】random库
    【HTML】iframe嵌套界面自适应,可高度自由收缩
    【HTML】三种方法使HTML单页面输入密码才能访问
    维护
    投喂记录
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5725041.html
Copyright © 2011-2022 走看看