zoukankan      html  css  js  c++  java
  • POJ 1845 Sumdiv

    Sumdiv
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 10515   Accepted: 2477

    Description

    Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).

    Input

    The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.

    Output

    The only line of the output will contain S modulo 9901.

    Sample Input

    2 3

    Sample Output

    15

    Hint

    2^3 = 8.
    The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
    15 modulo 9901 is 15 (that should be output).

    Source

    求 A^B 的约数和 mod 9901

    把A因式分解成 p1^a1*p2^a2*..*pk^ak
    然后用约数求和函数

    这里关键问题是 有可能出现 gcd(pi-1,9901)!=1
    这样的话就不能求逆元了、、、、

    如果没有逆元
    那么 对于 1+p1+p1^2...p^n

    作以下处理
    n%2==1
    原式=(1+p+p^2+..p^(n/2))(1+p^(n/2+1))
    n%2==0
    n=n-1;
    原式=(1+p+p^2+..p^(n/2))(1+p^(n/2+1))+p^(n+1);

    二分递归求解

    我忘记考虑 a是9901的倍数情况了,那样 tp会为负,Wa的我好痛苦、、、

    #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> using namespace std; int x,y; #define Mod 9901 void EGcd(int a,int b) { if(b==0) { x=1; y=0; return ; } EGcd(b,a%b); int x0=y; y=x-a/b*y; x=x0; } int gcd(int a,int b) { int r; while(r=a%b){a=b;b=r;} return b; } #define N 10002 bool h[N]; int pm[N>>1]; void Getprime() { int cnt=1; int i,j; pm[0]=2; for(i=2;i<N;i+=2) h[i]=1; for(i=3;i<N;i+=2) if(!h[i]) { pm[cnt++]=i; for(j=i*i;j<N;j+=i) h[j]=1; } } int Pw(int a,int b) { int t; for(t=1;b>0;b=(b>>1),a=(a%Mod)*(a%Mod)%Mod) if(b&1) t=(t*a)%Mod; return t; } int bn(int a,int n) { if(n==2) { return (1+a+(a%Mod)*(a%Mod)%Mod)%Mod; } if(n==1) { return (1+a)%Mod; } if(n%2) { return bn(a,n/2)*(1+Pw(a,n/2+1)%Mod)%Mod; } n--; return bn(a,n/2)*(1+Pw(a,n/2+1)%Mod)%Mod+Pw(a,n+1); } int rc[12][2]; int main() { Getprime(); int a,b; int tp; while(scanf("%d %d",&a,&b)!=EOF) { if(a==0){printf("0\n");continue;} if(b==0||a==1){printf("1\n");continue;} tp=1; int m=(int)sqrt(a*1.0); int i,cnt=0; for(i=0;pm[i]<=m;i++) if(a%pm[i]==0) { rc[cnt][0]=pm[i]; rc[cnt][1]=0; while(a%pm[i]==0){a/=pm[i];rc[cnt][1]++;} cnt++; } if(a>1) { rc[cnt][0]=a;rc[cnt++][1]=1;} for(i=0;i<cnt;i++) { if(gcd(rc[i][0]-1,Mod)==1) { tp=tp*(Pw(rc[i][0],rc[i][1]*b+1)-1)%Mod; while(tp<0)tp+=9901;//忘记加这个、、、Wa好久 EGcd(rc[i][0]-1,9901); while(x<0)x+=9901; tp=tp*(x%9901)%9901; } else { tp=tp*bn(rc[i][0],rc[i][1]*b)%9901; } } printf("%d\n",tp); } return 0; }
  • 相关阅读:
    linux内核的配置
    数据库常用SQL语句(二):多表连接查询
    数据库常用SQL语句(三):子查询
    数据库常用SQL语句(一):常用的数据库、表操作及单表查询语句
    数据库管理系统软件的软件架构
    Java对象的序列化
    关于重写对象equals方法的问题
    对Spring的理解
    Myeclipse项目工程目录中各种Libraries的含义
    对JDBC的使用理解
  • 原文地址:https://www.cnblogs.com/372465774y/p/2734765.html
Copyright © 2011-2022 走看看