POJ 3696 极好的数论题目

View Code
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <bitset>
  7 #include <map>
  8 #include <vector>
  9 
 10 using namespace std;
 11 typedef long long llint;
 12 
 13 #define print(x) cout<<x<<endl
 14 #define input(x) cin>>x
 15 #define SIZE 45000
 16 
 17 inline int mul(int x)
 18 {
 19     return x*x;
 20 }
 21 
 22 int prime[SIZE],hash[SIZE];
 23 int ind,sz;
 24 int prime_factor[SIZE];
 25 vector<llint> factor;
 26 
 27 void init()
 28 {
 29     ind=0;
 30     bitset<SIZE> p;
 31     for(int i=2;i<SIZE/2;i++)
 32     {
 33         if(p[i]) continue;
 34         else
 35         {
 36             for(int j=2;i*j<SIZE;j++) p[i*j]=1;
 37         }
 38     }
 39 
 40     for(int i=2;i<SIZE;i++)
 41     {
 42         if(!p[i]) prime[ind++]=i;
 43     }
 44 }
 45 llint gcd(llint a,llint b)
 46 {
 47     if(a<b) return gcd(b,a);
 48     else if(a%b==0) return b;
 49     else return gcd(b,a%b);
 50 }
 51 
 52 llint eular(llint y)
 53 {
 54     llint ans=1;
 55     for(int i=0;i<ind && mul(prime[i])<=y;i++)
 56     {
 57         if(y%prime[i]==0)
 58         {
 59             ans*=(prime[i]-1);
 60             y/=prime[i];
 61         }
 62         while(y%prime[i]==0)
 63         {
 64             y/=prime[i];
 65             ans*=prime[i];
 66         }
 67     }
 68     if(y!=1) ans*=(y-1);
 69     return ans;
 70 }
 71 
 72 void dfs(llint iter,llint val=1)
 73 {
 74     if(iter==sz) factor.push_back(val);
 75     else
 76     {
 77         llint num=hash[iter];
 78         llint t=prime_factor[iter];
 79         llint t_val=val;
 80         for(int i=0;i<t;i++)
 81         {
 82             dfs(iter+1,t_val*num);
 83             t_val*=num;
 84         }
 85         dfs(iter+1,val);
 86     }
 87 }
 88 
 89 llint safemul(llint a,llint b,llint c)
 90 {
 91     llint ans=0;
 92     while(b)
 93     {
 94         if(b&1) ans+=a;
 95         if(b>=2) a=(a+a)%c;
 96         ans%=c;
 97         b>>=1;
 98     }
 99     return ans;
100 }
101 
102 llint fastmod(llint a,llint b,llint c)
103 {
104     if(b==0) return 1;
105     else if(b==1) return a%c;
106     else
107     {
108         llint tmp=fastmod(a,b>>1,c)%c;
109         tmp=safemul(tmp,tmp,c);
110         if(b&1) return (tmp*a%c)%c;
111         else return tmp%c;
112     }
113 }
114 
115 int slove(int x)
116 {
117     factor.clear();
118     memset(hash,0,sizeof(hash));
119     sz=0;
120     memset(prime_factor,0,sizeof(prime_factor));
121     llint y=9LL*x/gcd(8,x);
122     if(gcd(10,y)!=1) return 0;
123     llint e=eular(y);
124     //print(e<<' '<<y);
125     for(int i=0;i<ind && prime[i]*prime[i]<=e;i++)
126     {
127         while(e%prime[i]==0)
128         {
129             prime_factor[sz]++;
130             e/=prime[i];
131         }
132         hash[sz]=prime[i];
133         sz++;
134     }
135     hash[sz]=e;
136     prime_factor[sz++]++;
137     dfs(0,1);
138     sort(factor.begin(),factor.end());
139     for(int i=0;i<(int)factor.size();i++)
140     {
141         if(fastmod(10,factor[i],y)==1) return factor[i];
142     }
143     return 0;
144 }
145 
146 
147 int main()
148 {
149     int x,cas=1;
150     init();
151     while(scanf("%d",&x)!=EOF && x)
152     {
153         printf("Case %d: ",cas++);
154         print(slove(x));
155     }
156     return 0;
157 }

转载于:https://www.cnblogs.com/Wizmann/archive/2012/07/02/2573268.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值