hdu 4610 Cards(暴力+miller-rabin)
来源:互联网 发布:琵琶 知乎 编辑:程序博客网 时间:2024/06/09 15:22
题目链接:hdu 4610 Cards
解题思路
用素数筛选法先预处理出每个数的因子个数,因子和。因子个数肯定小于1e6,可以根据预处理的素数表直接判断是否为素数,但是因子和可能到达4百多万,所以直接用miller-rabin直接判素数。
判断因子积是否是平方和的部分,考虑因子个数,如果因子个数为奇数(即该数为平方数),则sqrt(i)必须是平方数才行。如果因子个数为偶数,则cnt/2为偶数时该数的因子积为平方数。
最后枚举一下哪些条件要满足,注意这里,因为有的条件附加值为负数。如果只枚举
代码
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <ctime>#include <algorithm>using namespace std;const int maxn = 1e6;const int maxm = 1e3 + 5;const int mod = 1e9 + 7;const int inf = 0x3f3f3f3f;typedef long long ll;int cnt[maxn+5], sum[maxn+5], vis[maxn+5], val[20];ll pow_mod(ll x, int n, ll mod) { ll ret = 1; while (n) { if (n&1) ret = ret * x % mod; x = x * x % mod; n >>= 1; } return ret;}bool miller_rabin(int n) { if (n <= maxn) return vis[n]; srand(time(0)); for (int i = 0; i < 10; i++) if (pow_mod(rand() % (n-1) + 1, n-1, n) != 1) return false; return true;}void presolve() { vis[1] = 1; for (int i = 2; i <= maxn; i++) { cnt[i]++, sum[i] += i; for (int j = i + i; j <= maxn; j += i) { cnt[j]++; sum[j] += i; vis[j] = 1; } } for (int i = 1; i <= maxn; i++) { vis[i] = 1^vis[i]; cnt[i]++, sum[i]++; } val[0] = 0; for (int i = 1; i < 16; i++) val[i] = val[i>>1] + (i&1);}bool judge (int s) { if (cnt[s]&1) { s = (int)sqrt(s); return cnt[s]&1; } return ((cnt[s]>>1)&1) == 0;}int N, K, C[20], extra[10];int getstatus(int x) { int s = 0; if (vis[x]) s |= 1; if (vis[cnt[x]]) s |= 2; if (miller_rabin(sum[x])) s |= 4; if (judge(x)) s |= 8; return s;}void init () { int a, b; scanf("%d%d", &N, &K); memset(C, 0, sizeof(C)); for (int i = 1; i <= N; i++) { scanf("%d%d", &a, &b); int s = getstatus(a); C[s] += b; printf("%d%c", val[s], i == N ? '\n' : ' '); } for (int i = 0; i < 4; i++) scanf("%d\n", &extra[i]);}int solve () { int ret = -inf, c[10]; for (int i = 0; i < (1<<16); i++) { int n = K, s = 0, g = 0; memset(c, 0, sizeof(c)); for (int j = 0; j < 16; j++) { if ((i&(1<<j)) == 0) continue; if (C[j]) { s |= j; n--; g += val[j]; c[val[j]] += C[j]-1; } else n = -1; } if (n < 0) continue; for (int j = 4; j >= 0; j--) { int tmp = min(n, c[j]); g += tmp * j; n -= tmp; } if (n) continue; for (int j = 0; j < 4; j++) { if ((s&(1<<j)) == 0) g += extra[j]; } ret = max(ret, g); } return ret;}int main () { presolve(); int cas; scanf("%d", &cas); while (cas--) { init(); printf("%d\n", solve()); } return 0;}
0 0
- hdu 4610 Cards(暴力+miller-rabin)
- hdu 4610 Cards (贪心+暴力)
- 【Miller-Rabin 素数判定】HDU
- hdu 2138 判断素数(Miller-Rabin算法)
- 质数判定(miller-rabin)
- miller-rabin
- miller-rabin
- Miller Rabin
- Miller-Rabin
- 大数判断素数(Miller-Rabin测试)
- HDU2138(Miller-Rabin素数检测)
- 素数测试(Miller-Rabin测试)
- 【BZOJ3667】Rabin-Miller算法(Pollard_pho算法)
- hdu 4910 Problem about GCD(Miller Rabin大素数检测)
- BZOJ3667: Rabin-Miller算法 (Miller-Rabin&&pol_rho&&特技快速乘学习笔记)
- hihocoder第72周 数论一·Miller-Rabin质数测试(Miller-Rabin质数测试)
- bzoj3667 Rabin-Miller算法【Rabin-Miller+pollard_rho】
- Miller - Rabin素数测试
- Codeforces Round #327 (Div. 1) C. Three States
- 需求挖掘业务
- Machine Learning学习路线
- IOS开发笔记14-预处理指令
- QPushButton 设置背景颜色
- hdu 4610 Cards(暴力+miller-rabin)
- 第七周项目4 队列数组
- XRay3
- C++ 命令模式
- 关于硬链接
- HTML基础知识
- sqlplus的显示问题
- Java的集合容器(下)
- cookie 和session 的区别详解