【题目概括】

计算\(C_n^k\)的因子个数。

【思路要点】

  • 首先考虑将组合数展开,展开后就是\(\frac {n!}{k!\times (n-k)!}\)。
  • 这样就是计算出这些质因子的个数,然后将插值相乘就是答案了。
  • 但是数据较大,所以我们考虑一开始先将所有答案预处理来。
  • 如果是暴力求解,那么就会超时。
  • 我们考虑用归纳法来计算,如果计算出\(C_{n}^{k}\),那么如何计算出\(C_n^{k+1}\)。
  • 那么将式子展开,就相差了\(k+1\)和\(n-k+1\),就\(O(n)\)计算一次。
  • 时间复杂度 \(\mathcal O(n^3)\)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long long ll;

const int N = 505;

int x, y, primeCnt;
bool ntPrime[N];
ll tot[N];
int prime[N];
ll ans[N][N];

void getPrime(int lim) {
  for (int i = 2; i <= lim; i++) {
    if (!ntPrime[i])
      prime[++primeCnt] = i;
    for (int j = 1; j <= primeCnt && i * prime[j] <= lim; j++) {
      ntPrime[i * prime[j]] = 1;
      if (i % prime[j])
        break;
    }
  }
}

void divide(int x, int tp) {
  for (int i = 1, cnt; i <= primeCnt; i++) {
    if (x % prime[i] == 0) {
      cnt = 0;
      while (x % prime[i] == 0) {
        x /= prime[i];
        cnt++;
      }
      tot[i] += tp * cnt;
    }
  }
}

ll solve(int x, int y) {
  for (int i = x; i >= (x - y + 1); i--)
    divide(i, 1);
  for (int i = 1; i <= y; i++)
    divide(i, -1);
  ll ans = 1;
  for (int i = 1; i <= primeCnt; i++)
    ans *= tot[i] + 1;
  return ans;
}

void init() {
  for (int i = 0; i <= 432; i++)
    for (int j = 0; j <= 432; j++)
      ans[i][j] = 1ll;
  for (int i = 1; i <= 432; i++) {
    memset(tot, 0, sizeof tot);
    ans[i][1] = solve(i, 1);
    for (int j = 2; j <= (i >> 1); j++) {
      divide(j, -1);
      divide(i - j + 1, 1);
      for (int k = 1; k <= primeCnt; k++)
        ans[i][j] *= tot[k] + 1;
    }
  }
}

int main() {
  getPrime(450);
  init();
  while (scanf("%d %d", &x, &y) != EOF) {
    y = min(y, x - y);
    printf("%lld\n", ans[x][y]);
  }
  return 0;
}

【POJ2992】Divisors的更多相关文章

  1. 【BZOJ】【4146】 【AMPPZ2014】Divisors

    暴力 由于值的范围很小($ \leq 2*10^6$),所以用一个cnt数组统计每个值有多少个数,然后从小到大,统计每个数的倍数即可. 根据调和数?的神奇性质= =这样是$O(nlogn)$的…… / ...

  2. 【BZOJ4146】[AMPPZ2014]Divisors

    [BZOJ4146][AMPPZ2014]Divisors Description 给定一个序列a[1],a[2],...,a[n].求满足i!=j且a[i]|a[j]的二元组(i,j)的个数. In ...

  3. Sigma Function (LightOJ - 1336)【简单数论】【算术基本定理】【思维】

    Sigma Function (LightOJ - 1336)[简单数论][算术基本定理][思维] 标签: 入门讲座题解 数论 题目描述 Sigma function is an interestin ...

  4. 【LeetCode】数学(共106题)

    [2]Add Two Numbers (2018年12月23日,review) 链表的高精度加法. 题解:链表专题:https://www.cnblogs.com/zhangwanying/p/979 ...

  5. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  6. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  7. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  8. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  9. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

随机推荐

  1. vue-cli 3 ----- 项目频繁发送‘sockjs-node/info’请求

    在vue-cli3跑项目时发现了这个问题,浏览器一直在频繁发送这个请求,导致联调时很不方便,而且本地开发时项目也不能实时更新. 看了网上很多的 (1)  解决方案, 大多都是直接去node_modul ...

  2. 联盟周赛2019810 csgo (动态规划、不下降子序列)

    今天起晚了...就做了俩题 难受的一批... 题目描述 著名第一人称射击游戏 csgo 因其优秀的平衡性,爽快的射击感和科学的战术配比赢得了世界广大玩家的好评. 在一局游戏中,分为两个阵营,他们的目标 ...

  3. [百度百科]PCI-E的速度

    在早期开发中,PCIe最初被称为HSI(用于高速互连),并在最终确定其PCI-SIG名称PCI Express之前,将其名称更改为3GIO(第三代I / O). 名为阿拉帕霍工作组(AWG)的技术工作 ...

  4. 利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

    题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个 ...

  5. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  6. zookeeper核心知识与投票机制详解

    Zookeeper数据模型与session机制:zookeeper的数据模型有点类似于文件夹的树状结构,每一个节点都叫做znode,每一个节点都可以有子节点和数据,就好像文件夹下面可以有文件和子文件夹 ...

  7. python中逐行打印

    方法一:readline函数 f = open("./code.txt") # 返回一个文件对象 line = f.readline() # 调用文件的 readline()方法 ...

  8. SVM支持向量机(1)

    一.SVM模型 1.函数间隔与几何间隔,哪一条线是最好的? (1)公式化问题. 分类模型:当里面的值小于0的时候就是-1,当里面的值是大于等于0的时候就是1 函数间隔:前面乘以y(i),是为了保持数值 ...

  9. java复习(3)继承

    一.继承为题的提出 ---------------------------------------------------- 我们知道面向对象的三大特性是:封装.继承和多态,可以知道继承在java应用 ...

  10. 解析html,提取元素参数

    r = s.get(loginurl, verify=False) dom = etree.HTML(r.content.decode("utf-8")) try: result[ ...