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\n",*i);
322             cout<<i->first<<endl;
323         }
324     }
325 }

明天就要去打铁了orz

时间: 2024-10-22 11:37:21

poj1811 数论的相关文章

NKOJ1236 a^b (数论定理的应用)

          a^b 对于任意两个正整数a,b(0<=a,b<10000)计算a b各位数字的和的各位数字的和的各位数字的和的各位数字的和. Input 输入有多组数据,每组只有一行,包含两个正整数a,b.最后一组a=0,b=0表示输入结束,不需要处理. Output 对于每组输入数据,输出ab各位数字的和的各位数字的和的各位数字的和的各位数字的和. Sample Input 2 3 5 7 0 0 Sample Output 8 5 思路: 数论定理:任何数除以9的余数等于各位数的和除

CodeForces 396A 数论 组合数学

题目:http://codeforces.com/contest/396/problem/A 好久没做数论的东西了,一个获取素数的预处理跟素因子分解写错了,哭瞎了,呵呵, 首先ai最大值为10^9,n为500,最坏的情况 m最大值为500个10^9相乘,肯定不能获取m了,首选每一个ai肯定是m的一个因子,然后能分解就把ai给分解素因子,这样全部的ai都分解了  就能得到m的 所有素因子 以及 所有素因子的个数,题目求的 是n个因子的 不同序列的个数,所以每次 只能选出n个因子,这n个因子由素因子

HDU 4861 Couple doubi(数论)

HDU 4861 Couple doubi 题目链接 题意:给定k,p,有k个球,每个球的值为1^i+2^i+...+(p-1)^i (mod p) (1 <= i <= k),现在两人轮流取球,最后球的值总和大的人赢,问先手是否能赢 思路:先手不可能输,非赢即平,那么只要考虑每种球的值, 利用费马小定理或欧拉定理,很容易得到该函数的循环节为p - 1, 那么i如果为p - 1的倍数,即为循环节的位置,那么每个值都为1,总和为p - 1 如果i不在循环节的位置,任取一个原根g,根据原根的性质,

UVA 10548 - Find the Right Changes(数论)

UVA 10548 - Find the Right Changes 题目链接 题意:给定a,b,c,表示货物的价值,求由A货物和B货物组成C货物有几种方法,判断有无解和是否有无限多种 思路:扩展欧几里得求通解,去计算上限和下限就能判断 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const long l

hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4542 小明系列故事--未知剩余系 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 889    Accepted Submission(s): 207 Problem Description "今有物不知其数,三三数之有二,五五数之有三,七七数之有

[施工中]良心数论.

/* Copyright: xjjppm Author: xjjppm Date: 08-08-17 11:36 Description: Number Theory */ #include <map> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> inline int input() { char c=getchar();int x=0,a=

信息学中的数论(一)

做oi题目的时候,遇到数论题会令我兴奋不已. 这一篇让我来聊一聊我学过的gcd,lcm,扩展欧几里得算法,逆元,组合数等. 这篇贴的代码都是未经过编译运行的,所以如果有错或有疑问请评论. 恩 那么什么是数论 和数学有关的非几何都是数论? 嘛,我也不知道定义,那么就草率地认为所有和数学有关的非计算几何知识都是数论吧. 我们先来聊一聊gcd. 这个东西,非常的有用. 它的名字叫最大公约数. 正常人都知道,有一个方法叫辗转相除法(证明略): int gcd(int a,int b) { if(!b)r

【数论Day3】进制问题 题解

数论进入第三天,进制问题是常用提醒,是数论的一个重要知识点,常考! 题面:http://www.cnblogs.com/ljc20020730/p/6935255.html 1.K进制数(Kbased.pas/c/cpp) 首先明确数据范围: [数据规模和约定] 对于40%的数据,a的长度不超过5. 对于100%的数据,a的长度不超过100000. 对于40%暴力枚举不多说,上代码: var t,i,k,tt:longint; a:qword; s:string; function pow(x,

Bzoj2219 数论之神

Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 954  Solved: 268 Description 在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢? Inpu