POJ题单 基础数论
文章目录
The Embarrassed Cryptographer POJ - 2635
题目
思路
大数取模……但是要加速
之前的大数取模都是1位1位
这个需要3位3位
就是千进制吧
代码
const int MAXN = 1e6+5;
bool is[MAXN];
int prime[MAXN], tot = 0;
void getprime()
{
memset(is, 1, sizeof(is));
is[0] = is[1] = 0;
for(int i = 2; i < MAXN; i++)
{
if(is[i])
{
prime[tot++] = i;
}
for(int j = 0; j < tot; j++)
{
if(i * prime[j] >= MAXN) break;
is[i * prime[j]] = 0;
if(i % prime[j] == 0) break;
}
}
}
int MOD(int *s, int _num, int index)
{
int n = index;
int num = 0;
for(int i = n; i >= 0; i--)
{
num = num * 1000 + s[i];
num %= _num;
}
return num % _num;
}
char a[105];
int trans[105];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
getprime();
long long k, l;
while(~scanf("%s%lld\n", &a, &l))
{
//cout << a << endl;
memset(trans, 0, sizeof(trans));
int len = strlen(a);
int index = 0;
if(len == 1 && a[0] == '0' && l == 0)
{
break;
}
int cur = 0;
for(int i = len - 1; i >= 0; i--)
{
if(cur == 0)
trans[index] = trans[index] + a[i] - '0';
if(cur == 1)
{
trans[index] = trans[index] + 10 * (a[i] - '0');
}
if(cur == 2)
{
trans[index] = trans[index] + 100 * (a[i] - '0');
}
cur++;
if(cur == 3)
{
cur = 0;
index++;
}
}
if(len % 3 == 0) index--;
int flg = 1;
int ans = -1;
/*for(int i = 0; i <= index; i++)
{
cout << trans[i];
}
cout << endl;*/
for(int i = 0; prime[i] < l; i++)
{
if(!MOD(trans, prime[i], index))
{
flg = 0;
ans = prime[i];
break;
}
}
if(!flg)
{
printf("BAD %d\n", ans);
}
else
{
printf("GOOD\n");
}
}
return 0;
}
Semi-prime H-numbers POJ - 3292
题目
思路
改一下素数筛,筛出H-prime(假设m个)
然后
m
2
m^2
m2求出所有的half-prime,前缀和求个数
代码
const int MAXN = 1e6+5;
bool is[MAXN];
ll hprime[MAXN], tot = 0;
void getprime()
{
memset(is, 1, sizeof(is));
for(int i = 5; i < MAXN; i++)
{
if(i % 4 != 1)
{
is[i] = 0;
}
if(is[i])
{
hprime[tot++] = i;
for(int j = 2; i *j < MAXN; j++)
{
is[i * j] = 0;
}
}
}
}
int ishalf[MAXN];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
getprime();
int cnt = 0;
//freopen("out.txt", "w", stdout);
for(int i = 0; i < tot - 1; i++)
{
for(int j = i; hprime[i] * hprime[j] <= 1000001 && j < tot; j++)
{
//cnt = max(cnt, hprime[i] * hprime[j]);
//cout << hprime[i] * hprime[j] << endl;
ishalf[hprime[i] * hprime[j]] = 1;
}
}
for(int i = 1; i < MAXN; i++)
{
ishalf[i] += ishalf[i - 1];
}
int n;
while(cin >> n, n)
{
cout << n << ' ' << ishalf[n] << endl;
}
return 0;
}
Sumdiv POJ - 1845
题目
思路
唯一分解+约数和定理
不过爆ll了
代码
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef __int64 LL;
const LL mod = 9901;
LL mul(LL a, LL b, LL n) //大数乘法,直接相乘会爆int64,需要逐位相乘
{
LL s = 0;
while (b)
{
if (b & 1)
s = (s + a) % n;
a = (a * 2) % n;
b = b >> 1;
}
return s;
}
LL pow_mod(LL a, LL b, LL n) //修改后的求次方,避免了爆int64
{
a = a % n;
LL s = 1;
while (b)
{
if (b & 1)
{
s = mul(s, a, n);
}
a = mul(a, a, n);
b = b >> 1;
}
return s;
}
int main()
{
LL a, b;
while (cin >> a >> b)
{
if (a <= 1 || b == 0)
{
cout << 1 << endl;
continue;
}
LL ans = 1, i, j, k, t, n, m;
n = (LL)sqrt(a + 0.5);
for (i = 2; i <= n; i++)
{
if (a % i == 0)
{
//if((i-1)%mod==0)cout<<"*"<<i<<endl;
//cout<<"*"<<endl;
t = 0;
while (a % i == 0)
{
a = a / i;
t++;
}
if ((i - 1) % mod == 0)
ans = ans * (pow_mod(i, t * b + 1, mod * (i - 1)) / (i - 1)) % mod;
else
ans = ans * (pow_mod(i, t * b + 1, mod) - 1) * pow_mod(i - 1, mod - 2, mod) % mod;
}
}
if (a > 1)
{
//if((a-1)%mod==0)cout<<"*"<<a<<endl;
if ((a - 1) % mod == 0)
ans = ans * (pow_mod(a, b + 1, mod * (a - 1)) / (a - 1)) % mod;
else
ans = ans * (pow_mod(a, b + 1, mod) - 1) * pow_mod(a - 1, mod - 2, mod) % mod;
}
cout << (ans + mod) % mod << endl;
}
return 0;
}