数论模板(转自他人)

来源:互联网 发布:时代光华 知乎 编辑:程序博客网 时间:2024/04/30 19:01
/*头文件求素数[1,n],返回素数个数得到区间 [a ,b ] 之间的素数求a*b%c求a^b%c求x的欧拉函数值求x的欧拉函数值快速求欧拉函数和素数。求解 a * x = b mod n求解 gcd (a,b) = a * x + b * y (切忌unsigned)x = a[i] mod m[i] .8求约数和模板,fac[]存储所求数的因数分解式给出随机数,可以简单的用rand()代替rabinmiller方法测试n是否为质数pollard_rho分解,给出N的一个非1因数,找出N的最小质因数用中国剩余定理解同余方程组a=bi(modni)进制转换牛顿迭代法求开方字符串s表示的数字对一个整数取摸得到素数m的原根,需要素数表满足gcd(n,i) = 1 并且 i <=m成立的i的个数求A^B一个数字的二进制表达式中1的个数得到一个数字的二进制表达式的第i位求第k个与n互素的数,需要素数表求解x^2 = a mod (n) 。n为素数.求解pell方程求pell方程的第i个解求解 x^2 - a*b*y^2 = 1。的最小解(pell)求离散对数A^x = B mod C  模板  c不一定要素数求最小x使得a^x = 1 mod n 保证pn<=L,pd<=L 并且pn/pd 最接近A.m<10, 一个这样的数:M = mmm...mm,要求M%k=0.求n所有的约数和状态背包+梅森素数求b^b^b…^b mod m (n个) 求最大的并且不大于n的最大反素数整数HASH ,用以统一每个数字出现的次数同上,速度较快的一种Sum(gcd(x,y) ) 1<=x,y<=n 大整数因数分解三分模板哥德巴赫猜想梅森合数的因数分解计算前n个Catalen数和 mod m 矩阵相关 */头文件#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <math.h>#include <time.h>#include <set>#include <map>#include <stack>#include <queue>#include <string>#include <bitset>#include <vector>#include <deque>#include <list>#include <sstream>#include <iostream>#include <functional>#include <numeric>#include <algorithm>using namespace std;template<class T>inline T iabs(const T& v) {return v<0 ? -v : v;}template<class T>inline T strTo(string s){istringstream is(s);T v;is>>v;return v;}template<class T>inline string toStr(const T& v){ostringstream os;os<<v;return os.str();}template<class T>inline int cMin(T& a, const T& b){return b<a?a=b,1:0;}template<class T>inline int cMax(T& a, const T& b){return a<b?a=b,1:0;}template<class T>inline int cBit(T n){return n?cBit(n&(n-1))+1:0;}#define ep 1E-10#define CLR(arr,v)   memset(arr, v, sizeof(arr))#define SQ(a)  ((a)*(a))#define DEBUG(a)     printf("%s = %s\n", #a, toStr(a).c_str())#define FOR(i,s,e) for( u64  (i)=(s); (i) < (e) ; i++)Const u64 inf3 = 0x15fffffffffffffffll;int inf4 = 0x7fffffffl;typedef long long u64;//求素数[1,n],返回素数个数bool is[1000010];//用来求素数[1,130000]int prm[100000];//用来保存素数int totleprm;//记录素数总个数void getprm(int n){    int i;    memset(is,1,sizeof(is));    is[1]=0;    prm[totleprm++]=2;    for (i=4; i<=n; i+=2) is[i]=0;    for (i=3; i*i<=n; i+=2)    if (is[i])    {        prm[totleprm++]=i;        for (int s=2*i,j=i*i; j<=n; j+=s)        is[j]=0;    }    for (; i<=n; i++)    if (is[i]) prm[totleprm++]=i;}//得到区间 [a ,b ] 之间的素数//注意:需要前 6000个素数 (一般)int subprm[100010];int getSubPrm(u64 a,u64 b){    u64 totl = 0,i,j;    bool sign[1000010];    memset(sign,true,sizeof(sign));    if (a < 2) a = 2;    u64 l = b - a + 1;    for ( i=0; i<totleprm;i++)    {        if ((j=prm[i]*(a/prm[i]))<a) j += prm[i];        if (j<prm[i]*prm[i]) j = prm[i] * prm[i];        for ( ; j<=b ; j+=prm[i]) sign[j-a] = false;    }    for (i=0;i<l;i++)    if (sign[i]) subprm[totl++] = a + i;    return totl; }//求a*b%c//要求:a,b的范围在hugeint范围的一般以内,在hugeint为unsigned __int64时,a,b需要是__int64能表示的数u64  power_mod(u64 A, u64  B, u64 C){      u64  R = 1, D = A;    while (B )    {        if (B&1) R = (R*D)%C;        D = (D*D)%C;        B >>=1;    }    return R;}//求a^b%c//要求:a,b的范围在__int64范围的一般以内,在__int64为unsigned __int64时,a,b需要是__int64能表示的数u64  power_mod(u64 A, u64  B, u64 C){    u64  R = 1, D = A;    while (B )    {        if (B&1) R = product_mod(R, D, C);        D = product_mod(D, D, C);        B >>=1;    }    return R;}//求x的欧拉函数值//注意:需要素数表u64  euler(u64  x){    int i ;    u64  res = x;    for (i = 0; prm[i] < (u64 )sqrt(x * 1.0) + 1 && i < totleprm; i++)    if (x % prm[i] == 0)    {        res = res / prm[i] *( prm[i] - 1);        while (x % prm[i] == 0 ) x/=prm[i];        }if (x > 1) res = res / x * (x-1);    return res;}//求x的欧拉函数值u64 phi[1000001];void euler(int maxn){    int i;    int j;    for (i = 2; i <= maxn; i++)    phi[i] = i;    for (i = 2; i <= maxn; i+=2)    phi[i] /=2;    for (i = 3; i <= maxn; i+=2)    if (phi[i] == i)    {        for (j = i; j<=maxn; j+=i)        phi[j] = phi[j] / i * (i-1);    }} //快速求欧拉函数和素数。//注意:返回[1,maxn]中所有素数和每个数字的欧拉函数。//注意:prime[0] 存储区间内素数个数,prime[1] = 2;u64 phi[150010];char ok[150010]={0};u64 prm[150010]={0};u64 sum[150010]={0};int totleprm;int eulerAndPrm(int maxn){    u64 i,j;int totleprm=0;phi[1]=1;     for(i=2;i<=maxn;i++)     {      if(ok[i]==0)      {       prm[totleprm++]=i;1       phi[i]=i-1;      }      for(j=0;j<totleprm && prm[j]*i<= maxn;j++)      {       ok[prm[j]*i]=1;       if(i%prm[j]==0)       {         phi[i*prm[j]]=phi[i]*prm[j];         break;       }       else         phi[i*prm[j]]=phi[i]*(prm[j]-1);      }     } return totleprm;}//求解 a * x = b mod n//注意:解存在数组ans[] 中。 返回解的个数int modeq(u64 a, u64 b, u64 n, u64 ans[]){    u64 e, i, d, x, y;    d = extgcd(a, n, x, y);    if (b % d >0) return 0;    else    {        e =  (x * (b / d)) %(n/d);        if (e < 0) e +=n/d;        for(i=0; i<1; i++)            ans[i] = (e + (i * (n/d) ))%(n);        return d;    }}//求解 gcd (a,b) = a * x + b * y (切忌unsigned)u64 extgcd(u64 a,u64 b,u64 &x,u64 &y){    if (b == 0) {x=1;y=0;return a;}    u64 d = extgcd(b, a%b,x,y);    u64 t = x; x = y; y = t - a/b * y;    return d;}//x = a[i] mod m[i] .//求解x.无解时返回-1.u64 china(int k, u64 a[],u64 m[]){    bool flag = false;    u64 e, x, y, i,d;    u64 result;    u64 a1,m1;    u64 a2,m2;    m1 = m[0]; a1 = a[0];   FOR(i,1,k)    {        m2 = m[i]; a2 = a[i];        d =  extgcd( m1, m2, x, y );        if ( (a2-a1) %  d !=   0  )        flag = 1;        result =  ( x *  ((a2-a1) /  d ) %  m2 +  m2 ) %  m2;        a1 = a1 + m1 * result;  //对于求多个方程        m1 = (m1 * m2) / d;     //lcm(m1,m2)最小公倍数;        a1 = (a1 % m1 + m1) % m1;    }    if (flag)    return -1;    else    return a1;} //二分计算(p^0 + p^1 + p^2 + p^3 ... p^n) mod mu64 getSum(u64 p, u64 n, u64 m){    if (n == 1)    return (p%m);    u64 k = getSum(p,(n)/2,m);    if (n % 2 == 0)    {        u64 k_help = power_mod(p,n/2,m);        return (k+product_mod(k_help,k,m) )%m;    }    else    if (n % 2 == 1)    {        u64 k_help = power_mod(p,n/2+1,m);       return (k+product_mod(k_help,k,m)+k_help )%m;    }}//求约数和模板,fac[]存储所求数的因数分解式u64 getDivSum(factor fac[],int n){    u64 ans = 1;    FOR(i,0,n)        {            ans *= getSum(fac[i].p,fac[i].b,9901);ans = ans % 9901;        }   return ans;}//给出随机数,可以简单的用rand()代替__int64 rAndom(){ __int64 a;        a  = rand();        a *= rand();        a *= rand();        a *= rand();        return a;}//rabinmiller方法测试n是否为质数int pri[]={2,3,5,7,11,13,17,19,23,29};bool isprime(__int64 n){    if(n<2)        return false;    if(n==2)        return true;    if(!(n&1))        return false;    __int64 k = 0, i, j, m, a;    m = n - 1;    while(m % 2 == 0)        m = (m >> 1), k++;    for(i = 0; i < 10; i ++)    {        if(pri[i]>=n)return 1;        a = power_mod( pri[i], m, n );        if(a==1)            continue;        for(j = 0; j < k; j ++)        {            if(a==n-1)break;            a = product_mod(a,a,n);        }        if(j < k)            continue;        return false ;    }    return true;}//pollard_rho分解,给出N的一个非1因数,//返回N时为一次没有找到__int64 pollard_rho(__int64 C, __int64 N){    __int64 I, X, Y, K, D;    I = 1;    X = rand() % N;    Y = X;    K = 2;    do    {        I++;        D = gcd(N + Y - X, N);        if (D > 1 && D < N) return D;        if (I == K) Y = X, K *= 2;        X = (product_mod(X, X, N) + N - C) % N;    }while (Y != X);    return N;}//找出N的最小质因数__int64 rho(__int64 N){    if (isprime(N)) return N;    do    {        __int64 T = pollard_rho(rand() % (N - 1) + 1, N);        if (T < N)        {              __int64 A, B;              A = rho(T);              B = rho(N / T);              return A < B ? A : B;        }    }    while (true);}//用中国剩余定理解同余方程组a=bi(modni)long solmodu(long z, long b[], long n[]){   int i;    long a,m,x,y,t;m=1 ;a=0;for(i=0; i<z; i++)  m*=n[i];for(i=0; i<z; i++)    {t=m/n[i];exEuclid(n[i],t,x,y);a=(a+t*y*b[i])%m;}return (a+m)%m;}//进制转换//将一个10进制数转为m进制。//返回转换后数的长度,存在数组a中,并且,第i位上的数字表示a[i] * ( m ^ i)int changExquisite(int a[],u64 n, int m){    int i = 0;    while (n > 0)    {        a[i++] = n % m;        n = n / m;    }    return i;}//牛顿迭代法求开方//注意:实际是二分double NT_sqrt(double n){    double m = 1;     while(fabs(m-(m+n/m)/2)>1e-6){    m=(m+n/m)/2;    }    return m;}//字符串s表示的数字对一个整数取摸u64 strmod(char *s,u64 t){    u64 sum=0;       int i,len=strlen(s);       for(i=0;i<len;i++)    {              sum=sum*10+s[i]-'0';              while(sum>=t)                     sum-=t;    }       return sum;}//得到素数m的原根,需要素数表//Phi 为m的欧拉函数值//注意:原跟存在条件2,4,p^m,2*p^mu64 getPrmRoot(u64 m,u64 phi){    if (m == 2)    return 1;    u64 fac[1000];    u64 n = phi;    int e = (int)(sqrt(0.0 + n) + 1);    int length = 0;    for (int i=0; i<totleprm && prm[i]*prm[i] <= phi; i++)    if (n % prm[i] == 0)    {        fac[length++] = phi/prm[i]; while ( n % prm[i] == 0) n/=prm[i];    }    if (n!=1)    fac[length++] = phi/n;    u64 g = 2;    while (g < m)    {        if (gcd(g,m) != 1)        {g++;continue;}        bool sign = true;        FOR(i,0,length)        if (power_mod(g,fac[i],m) == 1 )        {            sign = false;            break;        }        if (sign)        break;        g++;    }//表示原根不存在    if (g == m)    return -1;    return g;}//满足gcd(n,i) = 1 并且 i <=m成立的i的个数//初始化素数表int getEul(int n , int m){    int factor[100];    int num = 0;    int e = (int)(sqrt(0.0 + n) + 1);    for (int i=0; i<totleprm && prm[i] <= e; i++)    if ( n % prm[i] == 0)    {        factor[num++] = prm[i];        while ( n % prm[i] == 0 && n != 1)        n = n / prm[i];    }    if (n != 1)    factor[num++] = n;    int ans = 0;    FOR(i,1,(1<<num))    {        int sign = i;        int lcm = 1;        int time = 0;        int j = 0;        while (sign > 0)        {            if (sign % 2 == 1)            {                lcm = lcm * factor[j];                time++;            }            sign = sign >> 1;            j++;        }        if (time % 2 == 1)        ans += m/lcm;        else        ans -= m/lcm;    }    return m - ans;}//求A^Bu64  power(u64 A, u64  B){    u64  R = 1, D = A;    while (B )    {        if (B&1) R = R * D;        D = D * D;        B >>=1;    }    return R;}//一个数字的二进制表达式中1的个数int getOneNum(u64 n){    int sum = 0    while (n > 0)    {        if (n & 1)         sum ++;         n = n >> 1;    }    return sum;}//得到一个数字的二进制表达式的第i位int isOne(u64 n, int i){    if ((n & (1 << i) ) == 0)    return 0;    return 1;}//求第k个与n互素的数,需要素数表u64 kThPrim(u64 n, u64 k){    u64 nn = n;    u64 factor[100];    int num = 0;    for (int i=0; i<totleprm && prm[i]*prm[i] <= n; i++)    if (nn % prm[i] == 0)    {        factor[num++] = prm[i];        while (nn % prm[i] == 0 && nn != 1)        nn/=prm[i];    }    if (nn != 1)    factor[num++] = nn;u64 l = 1;//这里注意,上界必须足够大    u64 h = 1000000000;    u64 m;    while ( l < h)    {        m = ( l + h) >> 1;        u64 ans = m ;        FOR(i,1,(1<<num))        {            u64 lcm = 1;            u64 ans_help = 0;            int sum = 0;            FOR(j,0,num)             if ((i & (1 << i) ) != 0)                {                    sum++;                    lcm = lcm * factor[j];                }            if (sum & 1 )            ans -= m / lcm;            else            ans += m / lcm;        }         if (ans  ==  k)        {        while (gcd(m,n) != 1) m--;        return m;        }        if (ans < k)        l = m + 1;        else        h = m;    }    return 0;}//求解x^2 = a mod (n) 。n为素数.//注意:有解时.返回较小解x . 另外一解为 n-x.  u64 ModSqrt(u64 a,u64 n){u64 b,k,i,x;if(n==2)return a%n;if(power_mod(a,(n-1)/2,n)==1){if(n%4==3)x=power_mod(a,(n+1)/4,n);else{for(b=1;power_mod(b,(n-1)/2,n)==1;b++);i=(n-1)/2;k=0;do{i/=2;k/=2;if( (power_mod(a,i,n)*(u64)power_mod(b,k,n)+1)%n==0 )k+=(n-1)/2;}while(i%2==0);x=(power_mod(a,(i+1)/2,n)*(u64)power_mod(b,k/2,n))%n;}if(x*2>n)x=n-x;return x;}return -1;}//求解pell方程struct Pell{llong a,b,c;//a+b*sqrt(c)Pell():a(0),b(0),c(0){}Pell(llong aa,llong bb,llong cc){a=aa;b=bb;c=cc;}Pell operator*(const Pell &p){Pell ret;ret.a=a*p.a+b*p.b*c;ret.b=a*p.b+b*p.a;ret.c=c;return ret;}Pell operator^(int k){if(k==1)return *this;--k;Pell ret=*this,tmp=ret;while(k){if(k&0x1)ret=ret*tmp;tmp=tmp*tmp;k>>=1;}return ret;}inline void showans(){printf("%10lld%10lld\n",b,(a-1)>>1);}};//求pell方程的第i个解/*a * x ^ 2 – b * y ^ 2 = c;x1,y1为方程的一个最小特解.。x0, y0 为 x ^ 2 – aby^2 = 1的最小特解矩阵unit 为 解为x,y*/void pell(Mat UNIT, int i,u64 x1, u64 y1, u64 &x, u64 &y){       Mat k = po(UNIT,i);       x = k.matrix[0][0] * x1 + k.matrix[0][1] * y1;       y = k.matrix[1][0] * x1 + k.matrix[1][1] * y1;}//求解 x^2 - a*b*y^2 = 1。的最小解(pell)void pell_continue(int n, u64 &x0, u64 &y0){    int con[1000];    int num = 0,c;    double k = sqrt(n);    con[num++] =  (int)k;    k = k - (int)k;    while (1)    {        con[num++] = (int)(1 / k);        k = (1/k)-(int)(1/k);        x0= 1;        y0= con[num-1];        for (int i=num-2; i>=0; i--)        {            x0 += con[i]*y0;            c = x0;            x0 = y0;            y0 = c;        }        c = x0;        x0 = y0;        y0 = c;        if (x0 * x0 - n * y0 * y0  == 1)        return ;    }}//求离散对数A^x = B mod C  模板  c不一定要素数#include<iostream>#include<map>#include<cmath>using namespace std;typedef long long LL;const int maxn = 65535;struct hash{    int a,b,next;}Hash[maxn << 1];int flg[maxn];int top,idx;void ins(int a,int b){    int k = b & maxn;    if(flg[k] != idx){        flg[k] = idx;        Hash[k].next = -1;        Hash[k].a = a;        Hash[k].b = b;        return ;    }    while(Hash[k].next != -1){        if(Hash[k].b == b) return ;        k = Hash[k].next;    }    Hash[k].next = ++ top;    Hash[top].next = -1;    Hash[top].a = a;    Hash[top].b = b;}int find(int b){    int k = b & maxn;    if(flg[k] != idx) return -1;    while(k != -1){        if(Hash[k].b == b) return Hash[k].a;        k = Hash[k].next;    }    return -1;}int gcd(int a,int b){return b?gcd(b,a%b):a;}int ext_gcd(int a,int b,int& x,int& y){    int t,ret;    if (!b){x=1,y=0;return a;}    ret=ext_gcd(b,a%b,x,y);    t=x,x=y,y=t-a/b*y;    return ret;}int Inval(int a,int b,int n){    int x,y,e;    ext_gcd(a,n,x,y);    e=(LL)x*b%n;    return e<0?e+n:e;}int pow_mod(LL a,int b,int c){LL ret=1%c;a%=c;while(b){if(b&1)ret=ret*a%c;a=a*a%c;b>>=1;}return ret;}int BabyStep(int A,int B,int C){    top = maxn; ++ idx;     LL buf=1%C,D=buf,K;    int i,d=0,tmp;    for(i=0;i<=100;buf=buf*A%C,++i)if(buf==B)return i;    while((tmp=gcd(A,C))!=1){        if(B%tmp)return -1;        ++d;        C/=tmp;        B/=tmp;        D=D*A/tmp%C;    }    int M=(int)ceil(sqrt((double)C));    for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)ins(i,buf);    for(i=0,K=pow_mod((LL)A,M,C);i<=M;D=D*K%C,++i){        tmp=Inval((int)D,B,C);int w ;        if(tmp>0&&(w = find(tmp)) != -1)return i*M+w+d;    }    return -1;}int main(){    int A,B,C;    while(scanf("%d%d%d",&A,&C,&B)!=EOF,A || B || C){        B %= C;        int tmp=BabyStep(A,B,C);        if(tmp<0)puts("No Solution");else printf("%d\n",tmp);    }    return 0;}//求最小x使得a^x = 1 mod n //其中gcd(a,n)=1u64 getRemainOne(u64 a, u64 n){    u64 phi,min;    phi = euler(n);    min = phi;    for (int i=1; i*i <= phi; i++)        if (phi % i== 0)        {            if (power_mod(2,i,n) == 1 && i < min)                min = i;            if (power_mod(2,phi/i,n) == 1 && phi/i < min)                min = phi/i;        }return min;}//保证pn<=L,pd<=L 并且pn/pd 最接近A.void AppNum(double A, long L, long &pn, long &pd){    double min;    long i;    long j;    long N;    long D;        pn = -999999;        pd = 1;        min = 9999999;        for (D=1; D<=L; ++D)        {            N = (long)(D * A);            if (N > L)            {                break;            }            for (i=0; i<=1; ++i)            {                if (fabs(min - A) > fabs((double)(N+i)/(double)D - A))                {                    pn = N+i;                    pd = D;                    min = (double)(N+i)/(double)D;                }            }        }        if (pn == -999999)        {            for (D=1; D<=L; ++D)            {                for (N=1; N<=L; ++N)                {                    if (fabs(min - A) > fabs((double)N/(double)D - A))                    {                        pn = N;                        pd = D;                        min = (double)N/(double)D;                    }                }            }        }}//m<10, 一个这样的数:M = mmm...mm,要求M%k=0.//返回M的位数,不存在返回-1int calNumMul(u64 k,int m){        u64 L = k;        L = 9 * L /gcd(9*L,m);        u64 phi = euler(L);        u64 min = phi;        for (int i=1; i*i <= phi; i++)        if (phi % i == 0)        {            if (power_mod(10,i,L) == 1 && i < min)            min = i;            if (power_mod(10,phi/i,L) == 1 && i < min)            min = phi/i;        }        if (min < phi)        return min;        return -1;}//求n所有的约数和//注意:最快是打表/*  int val[500001] = {0};    for(int i = 1; i <= 250000; i++)        for(int j = i<<1; j <= 500000; j += i)            val[j] += i;*/u64 getdiv(u64 num){    u64 divs[10000], divn[10000];    u64 d = 1, top = u64(sqrt(double(num))), divl = 0;    while(d <= top){        if(d < 3) d++;        else d += 2;        u64 cnt = 0;        while(num % d == 0){            cnt++;            num /= d;        }        if(cnt){            divs[divl] = d;            divn[divl++] = cnt;            top = int(sqrt(double(num)));        }    }    if(num > 1){        divs[divl] = num;        divn[divl++] = 1;    }    u64 ret = 1;    for(u64 i = 0; i < divl; i++){        u64 j = divn[i];        u64 k = 1, l = divs[i];        while(j--){            k += l;            l *= divs[i];        }        ret *= k;    }    return ret;}/*状态背包+梅森素数给定k个数,p1,p2...pk,计算n=p1^e1*p2^e2*...*pi^ei*...*pk^ek (0<=ei<=10, no all ei==0)m是n的因子和,如果m是2的幂指数次即存在x使得m=2^x,求最大的x,不存在输出NO把n写成质因子的幂指数成绩,底数均为质数,n=x1^a1*x2^a2....m=(1+x1+x1^2...x1^a1)*(1+x2+x2^2...x2^a2)....要使得m=2^x,显然a1,a2,a3...都必须为1那么x1,x2,x3就必须为梅森数了,对于输入的数只能是若干不同的梅森素数的积,如果某个数不是,那么把他踢出掉标记下它能够组合的状态,找个和最大的即可 */#include <stdio.h>#include <string.h>#include <iostream>using namespace std;#define FOR(i,s,e) for (int (i)=(s);(i)<(e);i++)int MePrm[]= {(1<<2)-1,(1<<3)-1,(1<<5)-1,(1<<7)-1,(1<<13)-1,(1<<17)-1,(1<<19)-1, (1<<31)-1};intnum[]={2,3,5,7,13,17,19,31};int sum[300];int use[300];void init(){memset(sum,0,sizeof(sum));FOR(i,1,256)FOR(j,0,8)if ((i & (1<<j)) !=0)sum[i]+=num[j];}int main(){init(); int n;int t;while (scanf("%d",&t)!=EOF){memset(use,0,sizeof(use));use[0]=1;FOR(i,0,t){bool sign = true;scanf("%d",&n);//初始状态设00000000int k = 0;FOR(j,0,8)if (n%MePrm[j] == 0){ int time = 0;while (n%MePrm[j] == 0&& n!=1 ){n/=MePrm[j];time++;}//符合要求,含有第j个梅森素数的1次方。修改状态 if (time == 1)k|=(1<<j);else{sign = false;break;} }if (!sign || n > 1 || k==0 ) continue;FOR (j,1,256)//假设j=10100110,k=00000110.必须下列条件,j状态合法(1^1=0.1^0=1.)if ((j&k) == k && use[(j^k)] == 1) {use[j]=1;}}int max = 0;FOR(j,1,256)//根据枚举的所有可能的状态,求该状态的最大值if (use[j] && max < sum[j]) max=sum[j];if (max == 0)printf("NO\n");elseprintf("%d\n",max);}return 0;}//求b^b^b…^b mod m (n个) //注意这个函数u64 newMod(u64 n, u64 m){if (n < m) return n; return n%m+m;}u64 product_mod(u64 a,u64 b,u64 c){    u64 ret=0,tmp=newMod(a,c);    while(b)    {        if(b&0x1)            if((ret+=tmp)>=c)                ret-=c;            if((tmp<<=1)>=c)                tmp-=c;            b>>=1;    }    return ret;}u64  power_mod(u64 A, u64  B, u64 C){ if (B == 0) return 1%C;    u64  R = 1, D = A;    while (B ){//注意这行,也可以调用product_mod        if (B&1) R =newMod(R*D,C);        D = newMod(D*D,C);        B >>=1;    }    return R;}u64 f(u64 b_v,u64 n, u64 m_v){  if (m_v == 1) return 0;  if (n == 1) return newMod(b_v,m_v);  u64 ph=euler(m_v);  u64 k = f(b_v,n-1,ph);  return power_mod(b_v,k,m_v);}   //求最大的并且不大于n的最大反素数//反素数:对于i<x ,必有g(i)<g(x).g(x)表示x的约数个数//性质:为p0^a0*p1^a1…pi^ai.并且a0<=a1<=…<=aiint prm[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};u64  sum;u64 max_un_prm;void bfs(u64 n, int k,u64 value, u64 max_value,int max_time){    if (n < value) return ;    if (max_value > sum || max_value == sum && value < max_un_prm)    {sum = max_value;max_un_prm = value;}    u64 n_help = prm[k];    int time = 1;    while (value <= n && time <= max_time)    {         value*=prm[k];         bfs(n,k+1,value,max_value*(time+1),time);         time++;    }}int main(){    u64 n;    while (cin >> n)    {        sum = 0;        bfs(n,0,1,1,100);       cout << max_un_prm<<endl;;    }    return 0;}//整数HASH ,用以统一每个数字出现的次数#include <iostream>#include <math.h>#include <stdio.h>#include <string.h>using namespace std;inline int IABS(int t) {return t>0?t:-1*t;}int a, b, c, d, e;int ans;int hash[20000];int key[20000];int NUM = 16383, CH = 1111;inline void MakeHash(int value){int t =IABS(value);t &= NUM; while (true){  if (hash[t] == 0){hash[t] = 1;key[t] = value;break;}else{if (key[t] == value){hash[t]++;break;}else{t = (t + CH) & NUM;}}}}//求value出现次数inline void GetHash(int value){int t = IABS(value); t &= NUM;while (true){if (hash[t] == 0){break;}else{if (key[t] == -value){ans += hash[t];break;}else{t = (t + CH) & NUM;}}}}int main(){int i, j;while (scanf("%d %d %d %d", &a, &b, &c, &d ) !=EOF){memset (hash, 0, sizeof(hash));memset (key, 0, sizeof(key));if (a > 0 && b > 0 && c > 0 && d > 0){printf("0\n");continue;}for (i = -100; i <= 100; i++){for (j = -100; j <= 100; j++){if (i && j){MakeHash(a * i * i + b * j  * j);}}}ans = 0;for (i = -100; i <= 100; i++){for (j = -100; j <= 100; j++){ {if (i && j  ){GetHash(c * i * i  + d * j  * j );}}}}cout << ans << endl;}return 0;}//同上,速度较快的一种#define tmax 3000001struct NODE{int val;int tot;bool used;}hash[tmax]; //定位函数int locate(int s){int temp;temp =s;while (temp < 0) temp+=tmax;while (temp >= tmax)temp%=tmax;while (hash[temp].used && hash[temp].val != s){temp++;if (temp >= tmax ) temp-=tmax;}return temp;} //此为hash函数void insert_in_hash(int value){int s = locate(value);hash[s].used = true;hash[s].val = value;hash[s].tot++;}void GetHash(int s){s=-1*s;int t =locate(s);ans+=hash[t].tot;return ;}//Sum(gcd(x,y) ) 1<=x,y<=n //需要[1…n]的前n项和欧拉函数表,u64 gcdExtreme(u64 n){ u64 sum = sum_phi[n];          for (u64 i=2; i< (n)/2+1; )          {              u64 k = n / i;              u64 j = n / k;              j++;              u64 num = (i+j-1)*(j-i)/2;              sum += num * sum_phi[n/i];              i = j ;          }    return sum;}//大整数因数分解#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;typedef     __int64 u64;const int MAX = 100;const int MAXN = 30;#define INF 1000000000 u64 gcd(u64 a, u64 b) {if (a < b) return gcd(b,a);u64 c;while (b) {c=a%b;a=b;b=c;}return a;} u64 product_mod(u64 a,u64 b,u64 c){    u64 ret=0,tmp=a%c;    while(b)    {        if(b&0x1)            if((ret+=tmp)>=c)                ret-=c;            if((tmp<<=1)>=c)                tmp-=c;            b>>=1;    }    return ret;}u64 random() {      u64 a;      a = rand();      a *= rand();      a *= rand();      a *= rand();      return a;}u64 f(u64 x, u64 n) {      return (product_mod(x, x, n) + 1) % n;}u64 Pollard_Rho(u64 n) {      if(n <= 2) return 0;      if(! (n & 1)) return 2;      u64 i, p, x, xx;      for(i = 1; i < MAX; i ++) {           x = random() % n;           xx = f(x, n);           p = gcd((xx + n - x) % n, n);           while(p == 1) {                x = f(x, n);                xx = f(f(xx, n), n);                p = gcd((xx + n - x) % n, n) % n;           }           if(p) return p;      }      return 0;} u64 power_mod(u64 x, u64 c, u64 n) {      u64 z = 1;      while(c) {           if(c & 1) z =product_mod(z, x, n);           x = product_mod(x, x, n);           c >>= 1;      }      return z;} bool Miller_Rabin(u64 n) {      if(n < 2) return false;      if(n == 2) return true;      if(! (n & 1)) return false;      u64 i, j, k, m, a;      m = n - 1;      k = 0;      while(m % 2 == 0) {           m >>= 1; k ++;      }      for(i = 0; i < MAX; i ++) {           a = power_mod(random() % (n - 1) + 1, m, n);           if(a == 1) continue;           for(j = 0; j < k; j ++) {                if(a == n - 1) break;                a = product_mod(a, a, n);           }           if(j == k) return false;      }      return true;} u64 Prime(u64 a) {      if(Miller_Rabin(a)) return 0;      u64 t = Pollard_Rho(a);      u64 p = Prime(t);      if(p) return p;      return t;}u64 factor[MAXN];u64 facNum[MAX];//直接调用即可。因子存在factor中,相应系数存在facNum中,返回素因子个数.int BigNumRes(u64 a){    int m = 0;    int time=0;    u64 t;    while(a > 1)    {        if(Miller_Rabin(a)) break;        t = Prime(a);        factor[m ++] = t;        time=0;        while (a%t==0 && a!=1) {time++;a/=t;}        facNum[m-1]=time;    }    if(a != 1) {factor[m ++] = a;facNum[m-1]=1;}    return m;}//三分模板//对于满足凸性的函数double Calc(Type a){    /* 根据题目的意思计算 */}void Solve(void){    double Left, Right;    double mid, midmid;    double mid_value, midmid_value;    Left = MIN; Right = MAX;    while (Left + EPS < Right)    {        mid = (Left + Right) / 2;        midmid = (mid + Right) / 2;        mid_area = Calc(mid);        midmid_area = Calc(midmid);        // 假设求解最大极值.        if (mid_area >= midmid_area) Right = midmid;        else Left = mid;    }}/*哥德巴赫猜想.每个不小于6的偶数都可以表示为两个奇素数之和;2.每个不小于9的奇数都可以表示为三个奇素数之和。梅森合数的因数分解将一个梅森合数因素分解。这里用到一个性质,2^p-1 的梅森合数,约数形式必须时候 2*h*p +1.枚举p,h即可。//分解梅森合数2^k-1*/ int prm[]={11,23,29,37,41,43,47,53,59};//k为prm[]中一个int MesanCom(int k,u64 fac[]){int num =0;u64 n = ((u64)(1)<<k)-1;for (int j=1; (u64)(2*k*j+1)*(u64)(2*j*k+1) <= n; j++ )if (n % (2*k*j+1) == 0){fac[num++] = (u64)(2*k*j+1);while (n % (2*k*j+1) == 0)n/=(2*k*j+1);}if (n!=1) fac[num++] = n;return num;}//计算前n个Catalen数和 mod m .C[n]=(4n-2)/(n+1*)C[n]。需要素数表const int maxN=100010; int totle_prm_m[maxN]; int prm_m[100];//存储m的素因子u64 euler_m;//存m欧拉函数值int num_prm_m=0;void init(int m){ num_prm_m = 0;euler_m=m; memset(totle_prm_m,0,sizeof(totle_prm_m));for (int i=0; i<totleprm && prm[i] * prm[i] <= m; i++)if (m % prm[i] == 0){euler_m = euler_m * (prm[i]-1)/prm[i];if (prm[i] <= maxN)prm_m[num_prm_m++]=prm[i]; while (m!=1 && m % prm[i] == 0) m/=prm[i];}if (m!=1){euler_m = euler_m * (m-1) / m;if (m <= maxN)prm_m[num_prm_m++]=m; }  }u64 SumCatalanModM(u64 n,u64 m){     init(m);  u64 a = 1;u64 b = 1;u64 ans = 0;u64 a_help; int time;int t; FOR(i,1,n+1){//分子 t = 4*i-2; FOR(j,0,num_prm_m)if (t % prm_m[j] == 0){  time = 0;while (t!=1 && t % prm_m[j] == 0){time++;t/=prm_m[j];} totle_prm_m[prm_m[j]]+=time;}a = (a*t)%m;t = i+1;  FOR(j,0,num_prm_m)if (t % prm_m[j] == 0){  time = 0;while (t != 1  && t % prm_m[j] == 0){time++;t/=prm_m[j];}totle_prm_m[prm_m[j]]-=time;}//分母b=(b*t)%m;a_help=a;FOR(j,0,num_prm_m)if (totle_prm_m[prm_m[j]])a_help = (a_help*power_mod(prm_m[j],totle_prm_m[prm_m[j]],m) ) % m; ans=(ans+(a_help*power_mod(b,euler_m-1,m))%m)%m; }return ans;}//矩阵相关 #define N 20typedef long long u64;struct Mat{u64 matrix[N][N];int r,l;};//单位矩阵Mat ONE;int p;//矩阵乘法Mat mul(Mat a, Mat b){int i, j, k;Mat c;for (i = 0; i < a.r; i++)for (j = 0; j < b.l; j++){c.matrix[i][j] = 0;for (k = 0; k < a.l; k++){c.matrix[i][j] +=  (a.matrix[i][k]*b.matrix[k][j])%p;c.matrix[i][j]%=p;}}    c.r = a.r ;    c.l = b.l;return c;}//高次矩阵幂Mat mat_Power (Mat a,u64 n){    if (n == 0) return ONE;    if (n == 1)    return a;    Mat ans;    Mat k = mat_Power(a, n/2);    ans.l=ans.r=a.l;    if (n % 2 == 0)    ans= mul(k,k);    else    ans= mul(mul(k,k),a);    return ans;}//矩阵加法Mat add_mat(Mat a, Mat b){    Mat c;    FOR(i,0,a.r)        FOR(j,0,a.l)            c.matrix[i][j] = (a.matrix[i][j]+b.matrix[i][j])%p;    c.l = a.l;    c.r = a.r;    return c;}//计算a + a^2 +a^3...a^n Mat Sum_mat(Mat a, u64 n){    if (n == 1) return a;    //ONE 是单位矩阵    if (n == 0) return ONE;    Mat k = Sum_mat(a,n/2);    Mat sum_help;    Mat ans;    ans.r = ans.l = a.l;    if (n % 2 == 0)    {        sum_help =  mat_Power(a,n/2);        ans = add_mat(k, mul(sum_help, k) );    }    else    {        sum_help = mat_Power(a,n/2+1);        ans = add_mat(k , add_mat(sum_help, mul(sum_help, k)) );    }    return ans;}//外挂读入double get(){    char c;    double ret;    while (c=getchar(),c<'0'||c>'9');    ret=c-'0';    while (c=getchar(),c>='0'&&c<='9')        ret=ret*10+c-'0';    return ret;} 

原创粉丝点击