题目大意:

求将$100!$ 拆成$a*b$的方案数,其中$a<=b$并且它们的约数个数一样多。

思路:

先将$100!$质因数分解, 结果如图:

首先想到一个暴力DP, dp[i][j][k]表示考虑完前i个质数, 目前a有j个约数,b有k个约数的方案数。 用map保存状态。

答案就是sum(dp[25][j][j]).

但是状态数会很多(大概有1e8个状态),所以考虑 中途相遇法。 对前3个质数做一次DP, 然后对后面22个质数做一次DP。

最后答案就是 sum (dp1[3][i1][j1] * dp2[22][i2][j2])   条件是 i1 * i2 = j1 * j2.  即  i1 / j1 =  j2 / i2 .

一个优化是只保存 j和k互质的状态。 然后 最后 答案的时候 枚举 i1,j1,  在 dp2中 查找 j2 / i2 = i1 / j1的点 。

因为a<=b,所以最后答案还需要除以2.

代码:

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <set>
#include <cstring>
#include <map>
#include <queue>
using namespace std; typedef long long ll;
#define N 10000000
#define M 1100
typedef pair<int,int> pii; bool flag[N];
int p[N],phi[N]; struct node
{
ll x,y;
bool operator < (const node &t)const
{
return y*t.x<x*t.y;
}
node (ll _x = , ll _y = ){x = _x; y = _y;}
}; map<node, ll> mp; ll Gcd(ll x, ll y)
{
ll tmp;
while (y)
{
tmp = x % y;
x = y, y = tmp;
}
return x;
} void Get_Primes(int lim)
{
phi[]=;
for (int i=;i<=lim;i++)
{
if (!flag[i]) p[++p[]]=i,phi[i]=i-;
for (int j=;j<=p[] && i*p[j]<=lim;j++)
{
flag[i*p[j]]=true;
if (i%p[j]==)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
else phi[i*p[j]]=phi[i]*(p[j]-);
}
}
} map<pair<ll,ll>, ll> f[], g[];
int cnt[]; int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout); int n = ;
Get_Primes(n);
for (int i = ; i <= p[]; ++i)
{
int x = p[i];
while (x <= n) cnt[i] += n / x, x *= p[i];
} f[][make_pair(,)] = ;
for (int i = ; i <= ; ++i)
{
for (map<pair<ll,ll>, ll>::iterator it = f[i - ].begin(); it != f[i - ].end(); it++)
{
ll k1 = (*it).first.first, k2 = (*it).first.second;
for (int j = ; j <= cnt[i]; ++j)
{
ll kx = k1 * (j + ), ky = k2 * (cnt[i] - j + ) , d = Gcd(kx, ky);
f[i][make_pair(kx / d, ky / d)] += (*it).second;
}
}
}
g[][make_pair(,)] = ;
for (int i = ; i <= p[] - ; ++i)
{
for (map<pair<ll,ll>, ll>::iterator it = g[i - ].begin(); it != g[i - ].end(); it++)
{
ll k1 = (*it).first.first, k2 = (*it).first.second;
for (int j = ; j <= cnt[i + ]; ++j)
{
ll kx = k1 * (j + ), ky = k2 * (cnt[i + ] - j + ), d = Gcd(kx, ky);
g[i][make_pair(kx / d, ky / d)] += (*it).second;
}
}
}
for (map<pair<ll,ll>, ll>::iterator it = g[p[] - ].begin(); it != g[p[] - ].end(); it++)
{
ll x = (*it).first.first, y = (*it).first.second;
mp[node(x, y)] += (*it).second;
} ll res = ;
for (map<pair<ll,ll>, ll>::iterator it = f[].begin(); it != f[].end(); it++)
{
ll x = (*it).first.first, y = (*it).first.second;
res += (*it).second * mp[node(y, x)];
}
cout << res / << endl;
return ;
}

答案:543194779059

Split Divisibilities (Project Euler 598)的更多相关文章

  1. Python练习题 049:Project Euler 022:姓名分值

    本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...

  2. Python练习题 041:Project Euler 013:求和、取前10位数值

    本题来自 Project Euler 第13题:https://projecteuler.net/problem=13 # Project Euler: Problem 13: Large sum # ...

  3. Python练习题 039:Project Euler 011:网格中4个数字的最大乘积

    本题来自 Project Euler 第11题:https://projecteuler.net/problem=11 # Project Euler: Problem 10: Largest pro ...

  4. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  5. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  6. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  7. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  8. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  9. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

随机推荐

  1. 基本的Bootstrap模板

    <!DOCTYPE html> <html> <html lang="zh-cn"> <meta charset="UTF-8& ...

  2. flask配置选项中的TRAP_HTTP_EXCEPTIONS会阻止自动跳转

    参考:http://www.pythondoc.com/flask/config.html Flask 对象的 config 属性. 这是Flask自身放置特定配置的地方,同时也是flask扩展模块放 ...

  3. leetcode第一刷_Edit Distance

    最小编辑距离.非常经典的问题.今年微软实习生的笔试有一个这个的扩展版,牵扯到模板之类的,当时一行代码也没写出来. . dp能够非常优雅的解决问题.状态转移方程也非常明白.用pos[i][j]表示wor ...

  4. XSS跨站脚本测试用例

    '><script>alert(document.cookie)</script>='><script>alert(document.cookie)&l ...

  5. HA分布式集群一hadoop+zookeeper

    一:HA分布式配置的优势: 1,防止由于一台namenode挂掉,集群失败的情形 2,适合工业生产的需求 二:HA安装步骤: 1,安装虚拟机 1,型号:VMware_workstation_full_ ...

  6. es6 中的 模板字符串

    Template literals are string literals allowing embedded expressions. You can use multi-line strings ...

  7. RocketMQ的异步调用

    这个异步调用方法中传入一个final 回调对象. public void invokeAsyncImpl(final Channel channel, final RemotingCommand re ...

  8. Nehe OpenGL lesson 8

    lesson8 Blending: http://nehe.gamedev.net/tutorial/lessons_06__10/17010/ (也许须要特殊手段訪问) There was a re ...

  9. Django——20141014深入理解Django HttpRequest HttpResponse的类和实例

    深入理解Django HttpRequest HttpResponse的类和实例 了解META选项 了解中间件 理清所有模板传输模板变量的方式,并作出选择 Django模板系统:如何利用Django模 ...

  10. java 线程的几种状态(转载)

      java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在 ...