poj 1811Prime Test http://poj.org/problem?id=1811
坑点:re了好多发,一直以为dfs次数太多,检查了很多次都不觉得会爆,数组也开得足够大,最后一种可能就是除0了.。。。。pollard_rho中有一步(y-x)的操作可能出现<=0的情况。。。。这是个pollard_rho的基本题,可以用来做模板
/************************************************************** Problem:poj 1811 User: youmi Language: C++ Result: Accepted Time:704MS Memory:708K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <ctime> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\n",a) #define ptlld(a) printf("%I64d\n",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0xffffffffffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; ll ans; const int maxn=100000; ll fact[maxn]; const int Times=10; const int C=201; int cnt=0; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } ll q_mul(ll a,ll b,ll mod) { ll res=0; a%=mod; while(b) { if(b&1) res=(res+a)%mod; b>>=1; a=(a<<1)%mod; } return res; } ll q_pow(ll a,ll b,ll mod) { ll res=1; a%=mod; while(b) { if(b&1) res=q_mul(res,a,mod); b>>=1; a=q_mul(a,a,mod); } return res; } bool miller_rabin(ll n) { if(n<2) return false; if(n==2) return true; if(!(n&1)) return false; ll u=n-1; int tot=0; while(!(u&1)) { u>>=1;tot++; } rep1(i,Times) { ll x=rand()%(n-2)+2; if(x==n) continue; x=q_pow(x,u,n); ll pre=x; rep0(j,tot) { x=q_mul(x,x,n); if(x==1&&pre!=1&&pre!=n-1) return false; pre=x; } if(x!=1) return false; } return true; } ll pollard_rho(ll n,ll c) { ll x,y,d,i=1,k=2; x=rand()%(n-1)+1; y=x; while(1) { i++; x=(q_mul(x,x,n)+c)%n; d=gcd(n,(y-x+n)%n);//注意!!!!!!!!! if(d>1&&d<n) return d; if(y==x) return n; if(i==k) { y=x; k<<=1; } } } void Find(ll n,int k) { if(n==1) return ; if(miller_rabin(n)) { fact[++cnt]=n; if(n<ans) ans=n; return; } ll p=n; while(p>=n) p=pollard_rho(p,k--); Find(p,k); Find(n/p,k); } int main() { //freopen("in.txt","r",stdin); int T_T; scanf("%d",&T_T); ll n; for(int kase=1;kase<=T_T;kase++) { scanf("%lld",&n); if(miller_rabin(n)) printf("Prime\n"); else { cnt=0; ans=n; Find(n,C); printf("%lld\n",ans); } } return 0; }
poj 2429 GCD & LCM Inverse http://poj.org/problem?id=2429
思路:now=lcm/gcd 的因子是a,b所不同的,所以只需对now进行整数分解(因为Now比较大,所以用pollard_rho),分解出来的因子,相同因子一定分在一起,要不然gcd应该更大(至少应该乘这个相同因子)所以,又因为11个素数相乘的大小就差不多能达到10^18,所以只需对用dfs深搜一下(2^11层),或者把2^tot-1个状态一一列举就行了。。。dfs的速度更快
/************************************************************** Problem:poj 2429 User: youmi Language: C++ Result: Accepted Time:79MS Memory:148K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <ctime> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\n",a) #define ptlld(a) printf("%I64d\n",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef unsigned long long ll; const int maxn=100000; ll fact[maxn]; ll a[maxn]; const int C=201; const int Times=5; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } ll q_mul(ll a,ll b,ll mod) { ll res=0; while(b) { if(b&1) res=(res+a)%mod; b>>=1; a=(a<<1)%mod; } return res; } ll q_pow(ll a,ll b,ll mod) { ll res=1; while(b) { if(b&1) res=q_mul(res,a,mod); b>>=1; a=q_mul(a,a,mod); } return res; } bool miller_rabbin(ll n) { if(n<2) return false; if(n==2) return true; if(!(n&1)) return false; ll u=n-1; int tot=0; while(!(u&1)) { u>>=1;tot++; } rep0(i,Times) { ll x=rand()%(n-2)+2; x=q_pow(x,u,n); ll pre=x; for(int j=0;j<tot;j++) { x=q_mul(x,x,n); if(x==1&&pre!=1&&pre!=n-1) return false; pre=x; } if(x!=1) return false; } return true; } ll pollard_rho(ll n,ll c) { ll x,y,d,i=1,k=2; x=rand()%(n-1)+1; y=x; while(1) { i++; x=(q_mul(x,x,n)+c)%n; d=gcd(n,(y-x+n)%n); if(d>1&&d<n) return d; if(x==y) return n; if(i==k) { y=x; k<<=1; } } } int cnt; void Find(ll n,int k) { if(n==1) return ; if(miller_rabbin(n)) { fact[++cnt]=n; return ; } ll p=n; while(p>=n) p=pollard_rho(n,k--); Find(p,k); Find(n/p,k); } ll ans,n,m,maxa; int all; /**< 148K 94MS 这是另一种思路 void solve() { ll x,y; pair<ll,ll>ans=make_pair(1,n/m); ll mini=ans.first+ans.second; ll bit=(1ll<<all)-1; for(int i=1;i<=bit;i++) { x=1; for(int j=1;j<=all;j++) { if(i&(1ll<<(j-1))) x*=a[j]; } y=maxa/x; if(x<y&&x+y<mini) { mini=x+y; ans.first=x; ans.second=y; //printf("x->%llu y->%llu mini->%llu\n",x,y,mini); } } printf("%llu %llu\n",ans.first*m,m*ans.second); } */ void dfs(ll cur,int temp) { if(temp>all) return; if(ans+maxa/ans>cur*a[temp]+maxa/(cur*a[temp])) { ans=cur*a[temp]; } dfs(cur*a[temp],temp+1); dfs(cur,temp+1); } bool cmp(ll c,ll b) { return c<b; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%llu%llu",&m,&n)) { if(n==m) { printf("%llu %llu\n",n,m); continue; } maxa=n/m; cnt=0; Find(maxa,C); sort(fact+1,fact+cnt,cmp); all=1; a[all]=fact[1]; for(int i=2;i<=cnt;i++) { if(fact[i]!=fact[i-1]) { a[++all]=fact[i]; } else a[all]*=fact[i]; } ans=a[1]; dfs(a[1],2); ll ans2=maxa/ans; ll temp; if(ans>ans2) { temp=ans; ans=ans2; ans2=temp; } printf("%llu %llu\n",ans*m,m*ans2); } return 0; }
不为失败找借口,只为成功找方法