• poj1811 数论


    题意:判断一个数是否是质数+分解质因数

    sol:模板题

    分解质因数用xudyh模板,注意factor返回的是无序的,factorG返回是从小到大的顺序(包括了1)

    判断质数用kuangbin随机化模板

      1 #include <cstdlib>
      2 #include <cctype>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <string>
      9 #include <iostream>
     10 #include <map>
     11 #include <set>
     12 #include <queue>
     13 #include <stack>
     14 #include <bitset>
     15 #include <list>
     16 #include <cassert>
     17 #include <complex>
     18 using namespace std;
     19 #define rep(i,a,n) for (int i=a;i<n;i++)
     20 #define per(i,a,n) for (int i=n-1;i>=a;i--)
     21 #define all(x) (x).begin(),(x).end()
     22 //#define fi first
     23 #define se second
     24 #define SZ(x) ((int)(x).size())
     25 #define TWO(x) (1<<(x))
     26 #define TWOL(x) (1ll<<(x))
     27 #define clr(a) memset(a,0,sizeof(a))
     28 #define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m)
     29 typedef vector<int> VI;
     30 typedef vector<string> VS;
     31 typedef vector<double> VD;
     32 typedef long long ll;
     33 typedef long double LD;
     34 typedef pair<int,int> PII;
     35 typedef pair<ll,ll> PLL;
     36 typedef vector<ll> VL;
     37 typedef vector<PII> VPII;
     38 typedef complex<double> CD;
     39 const int inf=0x20202020;
     40 const ll mod=1000000007;
     41 const double eps=1e-9;
     42 
     43 ll powmod(ll a,ll b)             //return (a*b)%mod
     44 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     45 ll powmod(ll a,ll b,ll mod)     //return (a*b)%mod
     46 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     47 ll gcd(ll a,ll b)                 //return gcd(a,b)
     48 { return b?gcd(b,a%b):a;}
     49 // head
     50 
     51 namespace Factor {
     52     const int N=1010000;
     53     ll C,fac[10010],n,mut,a[1001000];
     54     int T,cnt,i,l,prime[N],p[N],psize,_cnt;
     55     ll _e[100],_pr[100];
     56     vector<ll> d;
     57 
     58     inline ll mul(ll a,ll b,ll p) {     //return (a*b)%p
     59         if (p<=1000000000) return a*b%p;
     60         else if (p<=1000000000000ll) return (((a*(b>>20)%p)<<20)+(a*(b&((1<<20)-1))))%p;
     61         else {
     62             ll d=(ll)floor(a*(long double)b/p+0.5);
     63             ll ret=(a*b-d*p)%p;
     64             if (ret<0) ret+=p;
     65             return ret;
     66         }
     67     }
     68 
     69     void prime_table(){     //prime[1..tot]: prime[i]=ith prime
     70         int i,j,tot,t1;
     71         for (i=1;i<=psize;i++) p[i]=i;
     72         for (i=2,tot=0;i<=psize;i++){
     73             if (p[i]==i) prime[++tot]=i;
     74             for (j=1;j<=tot && (t1=prime[j]*i)<=psize;j++){
     75                 p[t1]=prime[j];
     76                 if (i%prime[j]==0) break;
     77             }
     78         }
     79     }
     80 
     81     void init(int ps) {                 //initial
     82         psize=ps;
     83         prime_table();
     84     }
     85 
     86     ll powl(ll a,ll n,ll p) {           //return (a^n)%p
     87         ll ans=1;
     88         for (;n;n>>=1) {
     89             if (n&1) ans=mul(ans,a,p);
     90             a=mul(a,a,p);
     91         }
     92         return ans;
     93     }
     94 
     95     bool witness(ll a,ll n) {
     96         int t=0;
     97         ll u=n-1;
     98         for (;~u&1;u>>=1) t++;
     99         ll x=powl(a,u,n),_x=0;
    100         for (;t;t--) {
    101             _x=mul(x,x,n);
    102             if (_x==1 && x!=1 && x!=n-1) return 1;
    103             x=_x;
    104         }
    105         return _x!=1;
    106     }
    107 
    108     bool miller(ll n) {
    109         if (n<2) return 0;
    110         if (n<=psize) return p[n]==n;
    111         if (~n&1) return 0;
    112         for (int j=0;j<=7;j++) if (witness(rand()%(n-1)+1,n)) return 0;
    113         return 1;
    114     }
    115 
    116     ll gcd(ll a,ll b) {
    117         ll ret=1;
    118         while (a!=0) {
    119             if ((~a&1) && (~b&1)) ret<<=1,a>>=1,b>>=1;
    120             else if (~a&1) a>>=1; else if (~b&1) b>>=1;
    121             else {
    122                 if (a<b) swap(a,b);
    123                 a-=b;
    124             }
    125         }
    126         return ret*b;
    127     }
    128 
    129     ll rho(ll n) {
    130         for (;;) {
    131             ll X=rand()%n,Y,Z,T=1,*lY=a,*lX=lY;
    132             int tmp=20;
    133             C=rand()%10+3;
    134             X=mul(X,X,n)+C;*(lY++)=X;lX++;
    135             Y=mul(X,X,n)+C;*(lY++)=Y;
    136             for(;X!=Y;) {
    137                 ll t=X-Y+n;
    138                 Z=mul(T,t,n);
    139                 if(Z==0) return gcd(T,n);
    140                 tmp--;
    141                 if (tmp==0) {
    142                     tmp=20;
    143                     Z=gcd(Z,n);
    144                     if (Z!=1 && Z!=n) return Z;
    145                 }
    146                 T=Z;
    147                 Y=*(lY++)=mul(Y,Y,n)+C;
    148                 Y=*(lY++)=mul(Y,Y,n)+C;
    149                 X=*(lX++);
    150             }
    151         }
    152     }
    153 
    154     void _factor(ll n) {
    155         for (int i=0;i<cnt;i++) {
    156             if (n%fac[i]==0) n/=fac[i],fac[cnt++]=fac[i];}
    157         if (n<=psize) {
    158             for (;n!=1;n/=p[n]) fac[cnt++]=p[n];
    159             return;
    160         }
    161         if (miller(n)) fac[cnt++]=n;
    162         else {
    163             ll x=rho(n);
    164             _factor(x);_factor(n/x);
    165         }
    166     }
    167 
    168     void dfs(ll x,int dep) {
    169         if (dep==_cnt) d.push_back(x);
    170         else {
    171             dfs(x,dep+1);
    172             for (int i=1;i<=_e[dep];i++) dfs(x*=_pr[dep],dep+1);
    173         }
    174     }
    175 
    176     void norm() {
    177         sort(fac,fac+cnt);
    178         _cnt=0;
    179         rep(i,0,cnt) if (i==0||fac[i]!=fac[i-1]) _pr[_cnt]=fac[i],_e[_cnt++]=1;
    180             else _e[_cnt-1]++;
    181     }
    182 
    183     vector<ll> getd() {
    184         d.clear();
    185         dfs(1,0);
    186         return d;
    187     }
    188 
    189     vector<ll> factor(ll n) {       //return all factors of n        cnt:the number of factors
    190         cnt=0;
    191         _factor(n);
    192         norm();
    193         return getd();
    194     }
    195 
    196     vector<PLL> factorG(ll n) {
    197         cnt=0;
    198         _factor(n);
    199         norm();
    200         vector<PLL> d;
    201         rep(i,0,_cnt) d.push_back(make_pair(_pr[i],_e[i]));
    202         return d;
    203     }
    204 
    205     bool is_primitive(ll a,ll p) {
    206         assert(miller(p));
    207         vector<PLL> D=factorG(p-1);
    208         rep(i,0,SZ(D)) if (powmod(a,(p-1)/D[i].first,p)==1) return 0;
    209         return 1;
    210     }
    211 }
    212 
    213 /* *************************************************
    214 * Miller_Rabin算法进行素数测试
    215 *速度快,可以判断一个  < 2^63的数是不是素数
    216 *
    217 **************************************************/
    218 const int S = 8; //随机算法判定次数,一般8~10就够了
    219 //计算ret  = (a*b)%c
    220 long long mult_mod(long long a,long long b,long long  c)
    221 {
    222     a %= c;
    223     b %= c;
    224     long long ret = 0;
    225     long long tmp = a;
    226     while(b)
    227     {
    228         if(b & 1)
    229         {
    230             ret += tmp;
    231             if(ret > c)ret -= c;//直接取模慢很多
    232         }
    233         tmp <<= 1;
    234         if(tmp > c)tmp -= c;
    235         b >>= 1;
    236     }
    237     return  ret;
    238 }
    239 //计算  ret = (a^n)%mod
    240 long long pow_mod(long long a,long long n,long long  mod)
    241 {
    242     long long ret = 1;
    243     long long temp = a%mod;
    244     while(n)
    245     {
    246         if(n & 1)ret = mult_mod(ret,temp,mod);
    247         temp = mult_mod(temp,temp,mod);
    248         n >>= 1;
    249     }
    250     return  ret;
    251 }
    252 //通过  a^(n-1)=1(mod n)来判断n是不是素数
    253 // n-1 = x*2^t中间使用二次判断
    254 //是合数返回true,不一定是合数返回false
    255 bool check(long long a,long long n,long long x,long long  t)
    256 {
    257     long long ret = pow_mod(a,x,n);
    258     long long last = ret;
    259     for(int i = 1; i <= t; i++)
    260     {
    261         ret = mult_mod(ret,ret,n);
    262         if(ret == 1 && last != 1 && last != n-1)return  true;//合数
    263         last = ret;
    264     }
    265     if(ret != 1)return true;
    266     else return false;
    267 }
    268 //**************************************************
    269 // Miller_Rabin算法
    270 //是素数返回true,(可能是伪素数)
    271 //不是素数返回false
    272 //**************************************************
    273 bool Miller_Rabin(long long  n)
    274 {
    275     if( n < 2)return false;
    276     if( n == 2)return true;
    277     if( (n&1) == 0)return false;//偶数
    278     long long x = n - 1;
    279     long long t = 0;
    280     while( (x&1)==0 )
    281     {
    282         x >>= 1;
    283         t++;
    284     }
    285     rand();/* *************** */
    286     for(int i = 0; i < S; i++)
    287     {
    288         long long a =  rand()%(n-1) + 1;
    289         if( check(a,n,x,t) )
    290             return false;
    291     }
    292     return true;
    293 }
    294 
    295 ll x,y,k,n;
    296 int _;
    297 int main() {
    298     Factor::init(200000);
    299     cin>>_;
    300     while (_--)
    301     {
    302         cin>>n;
    303         bool ok=Miller_Rabin(n);
    304         if (n==1)
    305         {
    306             cout<<1<<endl;
    307             continue;
    308         }
    309         else if (n==2)
    310         {
    311             cout<<"Prime"<<endl;
    312             continue;
    313         }
    314         if (ok) cout<<"Prime"<<endl;
    315         else
    316         {
    317             vector <PLL> p=Factor::factorG(n);
    318             //for (vector<ll>::iterator i=p.begin();i!=p.end();i++)
    319              //   cout<<*i<<" ";
    320              vector<PLL>::iterator i=p.begin();
    321             //printf("%d
    ",*i);
    322             cout<<i->first<<endl;
    323         }
    324     }
    325 }
    View Code

    明天就要去打铁了orz

  • 相关阅读:
    个人总结
    团队作业五
    个人项目五:个人回顾
    第二次冲刺
    第一次冲刺
    猜数字1
    随机数
    个人作业
    课后作业1
    作业
  • 原文地址:https://www.cnblogs.com/pdev/p/4115739.html
Copyright © 2020-2023  润新知