题意:判断一个数是否是质数+分解质因数
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\n",*i); 322 cout<<i->first<<endl; 323 } 324 } 325 }
明天就要去打铁了orz
时间: 2024-10-22 11:37:21