POJ2429
给两个数的gcd和lcm,输出满足条件的使得a+b最小的a和b
对lcm/gcd=ab这个数来讨论,枚举。找到sqrt(ab)周围第一个满足条件的a和b就好
然鹅,dfs。。
除了dfs外都是大数分解模板
注意,prime_factor内存的是无序的所有质因子,如36存的是 3 2 2 3
有序去重套个set就好力
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <ctime>
#include <utility>
using namespace std;
const int max_prime = 1e6;
const int s = 20;
typedef long long ll;
vector<ll> factor;
vector<ll> prime_factor;
ll x, y; //x:gcd, y:lcm
ll multi_mod(ll a, ll b, ll n)
{
a %= n;
b %= n;
ll res = 0;
while(b)
{
if(b & 1)
{
res += a;
if(res >= n) res -= n;
}
a <<= 1;
if(a >= n) a -= n;
b >>= 1;
}
return res;
}
ll pow_mod(ll x, ll n, ll mod)
{
if(n == 1) return x % mod;
x %= mod;
ll tmp = x;
ll res = 1;
while(n > 0)
{
if(n & 1) res = multi_mod(res, tmp, mod);
tmp = multi_mod(tmp, tmp, mod);
n >>= 1;
}
return res;
}
bool witness(ll a, ll n, ll u, ll t)
{
ll res = pow_mod(a, u, n);
ll last = res;
for(int i = 0; i < t; i++)
{
res = multi_mod(res, res, n);
if(res == 1 && last != 1 && last != n-1) return true;
last = res;
}
if(res != 1) return true;
else return false;
}
bool robin_miller(ll n) //判断是否素数
{
if(n < 2) return false;
if(n == 2) return true;
if(!(n & 1)) return false;
ll u = n - 1, t = 0;
while(!(u & 1)) u >>= 1, t++;
if(t >= 1 && (u & 1) == 1)
{
for(int i = 0; i < s; i++)
{
ll a = rand() % (n-1) + 1;
if(witness(a, n, u, t)) return false; //不是素数
}
}
return true; //是素数
}
ll gcd(ll a, ll b)
{
if(a == 0) return 1;
if(a < 0) return gcd(-a, b);
while(b)
{
ll t = a % b;
a = b;
b = t;
}
return a;
}
ll pollard_rho(ll x, ll c)
{
ll i = 1, x0 = rand() % x;
ll y = x0;
ll k = 2;
for(;;)
{
i++;
x0 = (multi_mod(x0, x0, x) + c) % x;
ll d = gcd(y - x0, x); //这里传给gcd的参数可能负数,注意分别讨论
if(d != 1 && d != x) return d; //这里表明找到了一个因子
if(y == x0) return x;
if(i == k)
{
y = x0;
k += k;
}
}
}
void find_fac(ll n)
{
if(n == 1) return;
if(robin_miller(n))
{
prime_factor.push_back(n);//set.insert(n);
return;
}
ll p = n;
while(p >= n) p = pollard_rho(p, rand() % (n-1) + 1);
find_fac(p);
find_fac(n / p);
}
ll dfs(int p, int len, ll res, ll m)
{
if(res > m) return 0;
if(p == len || res == m) return res;
ll tmp1 = dfs(p+1, len, res, m), tmp2;
//cout<<tmp1<<endl;
if(res * factor[p] + 0.0 > m) return tmp1;
else
{
tmp2 = dfs(p+1, len, res*factor[p], m);
//cout << tmp1<<" "<<tmp2 <<endl;
return tmp1 > tmp2 ? tmp1 : tmp2;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
while(cin >> x >> y)
{
srand(time(NULL));
prime_factor.clear();
factor.clear();
y /= x;
find_fac(y);
ll tmp = y;
// cout<<"prime factor"<<endl; for(int i = 0; i < prime_factor.size(); i++){ cout<< prime_factor[i]<<" "; } cout<<endl;
for(int i = 0; i < prime_factor.size(); i++)
{
ll res = 1;
while(tmp % prime_factor[i] == 0)
res *= prime_factor[i], tmp /= prime_factor[i];
//cout << res<<" ";
if(res != 1) factor.push_back(res);
}
//cout<<"factor : "; for(int i =0; i < factor.size(); i++){ cout<<factor[i]<<" "; }cout<<endl;
int len = factor.size();
ll m = (ll)sqrt(y + 0.0);
ll a = dfs(0, len, 1, m);
ll b = y / a;
printf("%lld %lld\n", a * x, b * x);
}
return 0;
}
POJ1930
据说是小学奥数题,为什么我上了大学还要活在小学成绩不好的阴影里QAQ
结论还是有用的吧,大概(但是谁要是出这题不是无聊么)
①完全循环小数
分母=循环节长度个9
如0.19191919 即分母为99
②混合小数
懒得写了,反正最后就是
0.12368686868=(12368-123)/99000
代码不打了耶耶耶(过分
POJ3126
每次只改变一个数且改变后也必须是素数,把一个素数a变成另一个素数b。问最少需要多少布
本来还以为可以趁机学习数位DP!
结果dp不好写最后直接bfs了QAQ
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 1e6 + 5 ;
int INf = 0x3f3f3f3f;
bool isprime[N];
int prime[1050];
void init()
{
memset(isprime,true,sizeof(isprime));
isprime[0]=isprime[1]=false;
isprime[2]=true;
for(int i = 2; i < N ;i++)
{
if(!isprime[i]) continue;
for(int j = 2; i*j< N;j++)
{
isprime[i*j]=false;
}
}
}
int vis[10000];
int step[10000];
int bfs(int a,int b)
{
int xx = a, yy = b;
queue<int> q;
memset(vis, 0, sizeof (vis));
memset(step, 0, sizeof (step));
q.push(a);
vis[a]=1;
while(!q.empty())
{
int x = q.front();
q.pop();
if(x == b)
{
return step[x];
}
xx=x-x%10;
for(int i= 0; i<= 9;i++)
{
//cout<<xx<<endl;
if(isprime[xx]&&!vis[xx])
{
vis[xx] = 1;
q.push(xx);
step[xx] = step[x] + 1;
//cout<<"push"<<endl;
}
xx++;
}
xx = x - x%100 + x%10;
for(int i = 0; i<= 9 ; i++)
{
//cout<<xx<<endl;
if(isprime[xx]&&!vis[xx])
{
vis[xx] = 1;
q.push(xx);
step[xx]=step[x] + 1;
//cout<<xx<<endl;
}
xx+=10;
}
xx = x - x%1000 + x%100 ;
for(int i = 0; i<= 9 ; i++ )
{
//cout<<xx<<endl;
if(isprime[xx] && !vis[xx])
{
vis[xx] = 1;
q.push(xx);
step[xx]=step[x] + 1;
//cout<<xx<<endl;
}
xx+=100;
}
xx = 1000 + x%1000;
for(int i = 0; i< 9 ; i++)
{
//cout<<xx<<endl;
if(isprime[xx] && !vis[xx])
{
q.push(xx);
vis[xx] = 1;
step[xx]=step[x] + 1;
//cout<<xx<<endl;
}
xx+=1000;
}
}
}
int main()
{
init();
int t, l, r;
int cnt = 0;
for(int i=2;i<=150;i++) if(isprime[i])cout<<i<<",";
cin>>t;
while(t--)
{
cin>> l >> r;
cout<<bfs(l,r)<<endl;
}
return 0;
}
POJ3421
智商题
当找不到规律的时候,就质因数分解试试。
注意质因数分解不要先打素数表,用map存还挺香,这个数据是2^20的多组数据1s的,直接写可以过
#include<map>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N = 1e6 ;
ull p[23];
ll prime[23] = {
2,3,5,7,11,13,17,19,23,29,
31,37,41,43,47,53,59,61,67,71,
73,79,83
};
void init()
{
p[1] = 1;
for ( ull i=2; i <= 23 ; i++ )
{
p[i] = p [i-1]*i;
}
}
map<ll,ll> factor;
int cnt = 0;
void find_factor(ll x)
{
for(int i=2 ;i*i<=x ; i++)
{
while( x%i == 0 )
{
//cout<<"push: "<<i<<endl;
x /= i;
factor[i]++;
}
}
if(x!=1)
factor[x]++;
}
int main()
{
ll a;
init();
while( cin>>a )
{
factor.clear();
find_factor(a);
//cout<<factor.size()<<" ";
ll ans = 1;
ll sum = 0;
map<ll,ll>::iterator I;
I = factor.begin();
while(I!=factor.end())
{
sum += I->second ;
//cout <<I.first<<" "<<I.second<<endl;
ans *= p[I->second] ;
I++;
}
//cout<<sum<<endl<<ans<<endl;
ans = p[sum]/ans;
cout<<sum<<" "<<ans<<endl;
}
return 0;
}
POJ3292
后面两道题都是快速幂,基本是板子orz
快速幂模板
ull qp(ull x,ull n,ull mod){
ull res = 1;
while(n>0)
{
if(n&1)
{
res =(res*x)%mod;
}
x =(x*x)%mod;
n >>= 1;
}
return res;
}
题目:
POJ3641
#include<iostream>
using namespace std;
const int mod=1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
bool prime(ull a){
if (a==1) return false;
if (a==2) return true;
for (ull i=2;i*i<a;i++)
{
if(a%i==0) return false;
}
return true;
}
ull qp(ull x,ull n,ull mod){
ull res = 1;
while(n>0)
{
if(n&1)
{
res =(res*x)%mod;
}
x =(x*x)%mod;
n >>= 1;
}
return res;
}
int main()
{
ull a,p;
while(cin>>p>>a && a+p!=0)
{
//cout<<qp(a,p,p)<<endl;
if(qp(a,p,p)==a%p)
if(!prime(p))
{
puts("yes");
continue;
}
puts("no");
}
return 0;
}
#include<iostream>
using namespace std;
const int mod=1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
bool prime(ull a){
if (a==1) return false;
if (a==2) return true;
for (ull i=2;i*i<a;i++)
{
if(a%i==0) return false;
}
return true;
}
ull qp(ull x,ull n,ull mod){
ull res = 1;
while(n>0)
{
if(n&1)
{
res =(res*x)%mod;
}
x =(x*x)%mod;
n >>= 1;
}
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
ull a,b,sum=0,m,h;
cin>>m>>h;
for(int i=0;i<h;i++)
{
cin>>a>>b;
//cout<<qp(a,b,m)<<endl;
sum+=qp(a,b,m);
sum%=m;
}
cout<<sum<<endl;
}
return 0;
}