1、HDU 5750 Dertouzos
官方题解:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 7e4;
int n, d;
bool vis[maxn];
int Prime[maxn];
int P_num = 0;
int mp[maxn];
void Init(void);
int Get_Mp(int x);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
Init();
while (T--) {
scanf("%d%d", &n, &d);
if (n-1 > d) {
if (d >= maxn) {
int t = (n-1)/d;
int pos = -1;
for (int i = 0; Prime[i] <= t; ++i) {
if (d%Prime[i] == 0) {
pos = i;
break;
}
}
int num = 0;
if (pos == -1) {
num = upper_bound(Prime, Prime+P_num, t) - Prime;
} else {
num = pos+1;
}
printf("%d\n", num);
} else {
int Min = min(mp[d], (n-1)/d);
int num = upper_bound(Prime, Prime+P_num, Min) - Prime;
printf("%d\n", num);
}
} else {
printf("0\n");
}
}
return 0;
}
void Init(void)
{
memset(vis, false, sizeof(vis));
memset(mp, -1, sizeof(mp));
for (int i = 2; i < maxn; ++i) {
if (!vis[i]) {
vis[i] = true;
Prime[P_num++] = i;
mp[i] = i;
int j = i*2;
while (j < maxn) {
if (mp[j] == -1) {
mp[j] = i;
}
vis[j] = true;
j += i;
}
}
}
}
2、POJ 1426 Find The Multiple
参考:http://blog.csdn.net/lyy289065406/article/details/6647917
同余模定理
(a*b)%n = (a%n * b%n)% n
(a+b)%n = (a%n + b%n)% n
前一步 (11*10+1)%6=2 即k=110 , k%6=2
当前步 (110*10+1)%6=2
由同余模定理 (110*10+1)%6 = ((110*10)%6+1%6 )%6 = ((110%6 * 10%6)%6 +1 )%6
不难发现下划线部分110%6等于 (11*10+0)%6 = 2
所以当前步(110*10+1)%6可以转变为 (2*10+1)%6=2
很显然地,这种处理把k=110 等价于 k=2
即用 前一步操作得到的余数 代替 当前步的k值
而n在200的范围内, 余数值不可能超过3位数, 这就解决了大数的问题
n=6时,求余操作进行了14次,对应地,bfs时*10的操作也进行了14次
令i=14,通过观察发现,i%2恰好就是 6 的倍数的最低位数字
i/2 再令 i%2 ,恰好就是 6 的倍数的次低位数字
循环这个操作,直到i=0,就能得到 6的 01倍数(一个01队列),倒序输出就是所求
这样就完成了 *10 操作到 %2 操作的过渡
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 1e6;
int n;
int mod[maxn];
int main()
{
// freopen("in.txt", "r", stdin);
while (scanf("%d", &n) != EOF && n != 0) {
mod[1] = 1%n;
int Count = 2;
while (mod[Count-1] != 0) {
mod[Count] = (mod[Count/2]*10 + Count%2) % n;
++Count;
}
--Count;
int num = 0;
while (Count) {
mod[num] = Count%2;
++num;
Count >>= 1;
}
while (num) {
--num;
printf("%d", mod[num]);
}
printf("\n");
}
return 0;
}
3、HDU 5793 A Boring Question
solution by uestc
这个推导看不太懂,我当时是暴力打表找的规律
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
int n, m;
ull Pow(ull x, ull n);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
ull ans = ((Pow(m, n+1) - 1) * Pow(m-1, mod-2)) % mod;
printf("%I64d\n", ans);
}
return 0;
}
ull Pow(ull x, ull n)
{
ull ret = 1;
ull t = x % mod;
while (n) {
if (n & 1) {
ret *= t;
ret %= mod;
}
n >>= 1;
t = (t*t) % mod;
}
return ret;
}
4、POJ 2649 Factovisors
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <bitset>
#include <ctime>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> Pair;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 7e4 + 10;
int prime_cnt = 0;
int n, m;
map<int, int> Map;
int prime[maxn];
bool vis[maxn];
int cnt(int x, int y);
void Init(void);
int main()
{
#ifdef __AiR
freopen("in.txt", "r", stdin);
#endif // __AiR_H_
Init();
while (scanf("%d %d", &n, &m) != EOF) {
if (n == 0 && m == 1) {
printf("%d divides %d!\n", m, n);
continue;
}
if (m == 0) {
printf("%d does not divide %d!\n", m, n);
continue;
}
Map.clear();
if (n >= m) {
printf("%d divides %d!\n", m, n);
} else {
int m_t = m;
for (int i = 0; i < prime_cnt; ++i) {
while (m_t % prime[i] == 0) {
++Map[prime[i]];
m_t /= prime[i];
}
if (m_t == 1) {
break;
}
}
if (m_t != 1) {
Map[m_t] = 1;
}
bool flag = true;
map<int, int>::iterator itr;
for (itr = Map.begin(); itr != Map.end(); ++itr) {
int a = itr->first, b = itr->second;
if (cnt(n, a) < b) {
flag = false;
break;
}
}
if (flag) {
printf("%d divides %d!\n", m, n);
} else {
printf("%d does not divide %d!\n", m, n);
}
}
}
return 0;
}
int cnt(int x, int y)
{
int ret = 0;
int t = x / y;
while (t) {
ret += t;
t /= y;
}
return ret;
}
void Init(void)
{
memset(vis, false, sizeof(vis));
for (int i = 2; i < maxn; ++i) {
if (!vis[i]) {
vis[i] = true;
prime[prime_cnt++] = i;
int j = i * 2;
while (j < maxn) {
vis[j] = true;
j += i;
}
}
}
}
5、CSU 1755 阶数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
typedef long long ll;
typedef pair<int, int> Pair;
const int INF = 0x7fffffff;
const int maxn = 4e4;
int prime[maxn], divisor[maxn];
bool vis[maxn];
int prime_cnt = 0, divisor_cnt = 0, mod;
void init(void);
int euler(int x);
int degree(int a, int phi);
int my_pow(int x, int n);
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int k, a, n;
init();
scanf("%d", &k);
while (k--) {
scanf("%d %d", &a, &n);
mod = n; divisor_cnt = 0;
if (__gcd(a, n) != 1) { printf("-1\n"); continue; }
printf("%d\n", degree(a, euler(n)));
}
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
int degree(int a, int phi) {
for (int i = 1; i * i <= phi; ++i) {
if (phi % i == 0) {
if (phi / i == i) {
divisor[divisor_cnt++] = i;
} else {
divisor[divisor_cnt++] = i;
divisor[divisor_cnt++] = phi / i;
}
}
}
sort(divisor, divisor + divisor_cnt);
int ret = 0;
REP(i, divisor_cnt) {
if (my_pow(a, divisor[i]) == 1) { ret = divisor[i]; break; }
}
return ret;
}
int my_pow(int x, int n) {
ll ret = 1, t = x % mod;
while (n) {
if (n & 1) { ret *= t; ret %= mod; }
n >>= 1; t *= t; t %= mod;
}
return (int)ret;
}
void init(void) {
memset(vis, false, sizeof(vis));
for (int i = 2; i < maxn; ++i) {
if (!vis[i]) {
prime[prime_cnt++] = i;
for (int j = i; j < maxn; j += i) { vis[j] = true; }
}
}
}
int euler(int x) {
int ret = x;
for (int i = 0; prime[i] * prime[i] <= x; ++i) {
if (x % prime[i] == 0) {
ret = ret / prime[i] * (prime[i] - 1); x /= prime[i];
while (x % prime[i] == 0) { x /= prime[i]; }
}
}
if (x != 1) { ret = ret / x * (x - 1); }
return ret;
}