zzuacm集训day2

来源:互联网 发布:safari windows版 编辑:程序博客网 时间:2024/04/29 17:52

1.素数

判断素数:

bool is_prime( int n){if ( n <= 1)return 0;int x = sqrt( n) + 0.5;for ( int i = 2; i <= x; i++){if ( n % i == 0)return 0;}return 1;}


 素数筛:

// 挨拉特斯托尼筛法// 处理后非素数的均为1int m = sqrt( n) + 0.5;memset( a, 0, sizeof a);a[1] = 1;for ( int i = 2; i <= m; i++){    if ( !a[i]){        for ( int j = i * i; j <= n; j += i){//避免i*i溢出            a[j] = 1;        }    }}Euler筛法int a[maxn] = {0};int prime[maxn], count = 0;for (int i = 2; i <= n; i++) {     if (a[i] == 0) {          prime[count++] = i;     }     for (int j = 0; j <count && i * prime[j] <= n; j++) {          a[i * prime[j]] = prime[j];          if (i % prime[j] == 0) break;     }}


米勒拉宾素数测试:

typedef unsigned long long LL;LL modular_multi(LL x,LL y,LL mo){    LL t;    x%=mo;    for(t=0;y;x=(x<<1)%mo,y>>=1)        if (y&1)            t=(t+x)%mo;    return t;}LL modular_exp(LL num,LL t,LL mo){    LL ret=1,temp=num%mo;    for(;t;t>>=1,temp=modular_multi(temp,temp,mo))        if (t&1)            ret=modular_multi(ret,temp,mo);    return ret;}bool miller_rabbin(LL n){    if (n==2)return true;    if (n<2||!(n&1))return false;    int t=0;    LL a,x,y,u=n-1;    while((u&1)==0) t++,u>>=1;    for(int i=0;i<20;i++)    {        a=rand()%(n-1)+1;        x=modular_exp(a,u,n);        for(int j=0;j<t;j++)        {            y=modular_multi(x,x,n);            if ( y == 1 && x != 1 && x != n - 1)                return false;            x=y;        }        if (x!=1)            return false;    }    return true;}



2.余数问题


随便写啦。。。


欧几里得算法:

即gcd,用于求最大公约数

int gcd( int a, int b){int c;while ( b){c = a % b;a = b;b = c;}return a;} 

扩展欧几里得算法:

扩展欧几里得求逆元:

// x y 为全局变量 void exgcd( ll a, ll b){if ( b == 0){x = 1;y = 0;return;}exgcd( b, a % b);int t = x;x = y;y = t - a / b * y;}



0 0