题目链接:

http://codeforces.com/contest/900/problem/D

题意:

给你 \(x\) 和 \(y\),让你求同时满足这两个条件的序列的个数:

\(a_1, a_2, ..., a_n (1 ≤ a_i)\)。

$ 1.$ $gcd(a_1, a_2, ..., a_n) = x $

$ 2.$ \(\sum_{i=1}^{n}a_i = y\)

题解:

可以发现,当\(y\%x!=0\)时,满足条件的序列不存在。让\(f(t)\)表示满足序列和为的 \(t\),且\(gcd\) 为 \(1\) 的序列的个数。那么答案就是 \(f(\frac{y}{x})\)。

显然,用隔板法可以证明,把一个数 \(x\) 分解成可以由几个数组成的序列有\(2^{x-1}\)个,假设\(k=\frac{y}{x}\),把其中是质数的情况保留,把非质数的情况减去就可以了,这里用记忆化,容斥一下就可以得到答案了。

代码:

#include<bits/stdc++.h>

using namespace std;

const int mod = 1e9+7;
#define ll long long std::map<int, int> mp;
ll qpower(ll a,ll b,ll mod)
{
ll ans = 1;
while(b>0)
{
if(b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
ll solve(int x)
{
if(x==1)return 1;
if (mp.count(x)) {
return mp[x];
}
mp[x] = qpower(2,x-1,mod);
for(int i=2;i*i<=x;i++) {
if(x%i==0){
mp[x] = (mp[x] - solve(x/i) + mod) % mod;
if(i!=x/i){
mp[x] = (mp[x] - solve(i) + mod) % mod;
}
}
}
mp[x] = (mp[x] - solve(1) + mod) % mod;
return mp[x];
}
int x,y;
int main(int argc, char const *argv[]) {
std::cin >> x >> y;
if(y%x!=0){
std::cout << "0" << '\n';
return 0;
}
std::cout << solve(y/x) << '\n';
return 0;
}

最新文章

  1. Flask 框架入门
  2. 表单input项使用label,同时引用Bootstrap库,导致input点击效果区增大
  3. 基于VC的声音文件操作(二)
  4. iOS-RegexKitLite导入错误
  5. Python自省(反射)指南
  6. Leetcode: Guess Number Higher or Lower II
  7. C的结构体使用
  8. jquery滚动条加载数据
  9. jstree使用小结(二)
  10. ORACLE+PYTHON实战:复制A表数据到B表
  11. Linux三剑客之awk最佳实践
  12. 201621123068 Week02-Java基本语法与类库
  13. 未完成的IT路停在回车键---2014年末总结篇
  14. SQLServer之创建DML AFTER UPDATE触发器
  15. PowerDesigner下载安装破解
  16. 再谈Retina下1px的解决方案
  17. bootstrap的使用集锦
  18. ES6基本使用
  19. RLP(转发注明出处)
  20. 回调函数ros::spin()与ros::spinOnce()

热门文章

  1. LRJ入门经典-0907万圣节的小L306
  2. Vijos——T1626 爱在心中
  3. 基于r-Kernel的LiteOS操作系统
  4. Android Developer:内存分析器
  5. Hive总结(五)hive日志
  6. .Net视图机制
  7. 缓存函数memorize
  8. 10.cocos2d坐标系
  9. ActiveMQ学习总结(3)——spring整合ActiveMQ
  10. 几个不错的开源的.net界面控件