如何计算等距二项式系数的和
How to compute sum of evenly spaced binomial coefficients
如何求取M的等距二项式系数之和
即(nCa+nCa+rnCa+2r+nCa+3r+…+nCa+kr)%M=
给定:0<=a<r、 a+kr<=n<a+(k+1)r、n<105,r<100
我的第一次尝试是:
int res = 0;
int mod=1000000009;
for (int k = 0; a + r*k <= n; k++) {
res = (res + mod_nCr(n, a+r*k, mod)) % mod;
}
但这不是有效的。所以看完这里在这篇论文中,我发现上述总和相当于:
求和[ω-ja*(1+ωj)n/r],对于0<=j<rω=ei2π/r是单位的原始rOrder(r)中查找此和的代码是什么
编辑:n可以达到105,r可以达到100。
原始问题来源:https://www.codechef.com/APRIL14/problems/ANUCBC
竞赛问题的社论:https://discuss.codechef.com/t/anucbc-editorial/5113
在6年后重新访问这篇文章后,我记不起我是如何将最初的问题陈述转化为我的版本的,尽管如此,我还是分享了原始解决方案的链接,以防有人想看看正确的解决方案。
二项式系数是多项式(1+x)^n的系数。x^a,x^(a+r)等的系数之和是多项式mod x^r-1中的(1+x)^n中的x^a的系数。多项式mod x^r-1可以由长度为r的系数数组指定。你可以通过重复平方来计算(1+x)^n mod(x^r-1,M),在每一步减少mod x^ r-1和mod M。这需要大约log_2(n)r^2步和O(r)空间的天真乘法。如果使用快速傅立叶变换对多项式进行乘法或幂运算,速度会更快。
例如,假设n=20,r=5。
(1+x) = {1,1,0,0,0}
(1+x)^2 = {1,2,1,0,0}
(1+x)^4 = {1,4,6,4,1}
(1+x)^8 = {1,8,28,56,70,56,28,8,1}
{1+56,8+28,28+8,56+1,70}
{57,36,36,57,70}
(1+x)^16 = {3249,4104,5400,9090,13380,9144,8289,7980,4900}
{3249+9144,4104+8289,5400+7980,9090+4900,13380}
{12393,12393,13380,13990,13380}
(1+x)^20 = (1+x)^16 (1+x)^4
= {12393,12393,13380,13990,13380}*{1,4,6,4,1}
{12393,61965,137310,191440,211585,203373,149620,67510,13380}
{215766,211585,204820,204820,211585}
这告诉您a的5个可能值的和。例如,对于a=1,211585=20c1+20c6+20c11+20c16=20+38760+167960+4845。
类似的东西,但你必须检查a
、n
和r
,因为我只是放了一些不考虑条件的东西:
#include <complex>
#include <cmath>
#include <iostream>
using namespace std;
int main( void )
{
const int r = 10;
const int a = 2;
const int n = 4;
complex<double> i(0.,1.), res(0., 0.), w;
for( int j(0); j<r; ++j )
{
w = exp( i * 2. * M_PI / (double)r );
res += pow( w, -j * a ) * pow( 1. + pow( w, j ), n ) / (double)r;
}
return 0;
}
mod
操作成本高昂,尽量避免
uint64_t res = 0;
int mod=1000000009;
for (int k = 0; a + r*k <= n; k++) {
res += mod_nCr(n, a+r*k, mod);
if(res > mod)
res %= mod;
}
我没有测试这个代码
我不知道你在这个问题上是否达成了共识,但实现这个公式的关键是要真正弄清楚w^I是独立的,因此可以形成一个环。简单地说,你应该考虑实现(1+x)^n%(x^r-1)或在环Z[x]/(x^r-1)中求出(1+x)^n如果感到困惑,我现在就给你一个简单的实现。
-
制作一个大小为r的向量。O(r)空间+0(r)时间
-
用0初始化这个向量,每个位置O(r)空间+O(r)时间
-
使该向量的前两个元素为1 O(1)
-
用快速求幂法计算(x+1)^n。每次乘法取O(r^2),有logn次乘法,因此O(r^2-log(n))
-
返回向量的第一个元素。O(1)复杂性O(r^2 log(n))时间和O(r)空间。使用傅立叶变换可以将这个r^2简化为r log(r)。乘法是如何完成的,这是具有幂中的mod的正则多项式乘法
向量p1(r,0);向量p2(r,0);p1[0]=p1[1]=1;p2[0]=p2[1]=1;现在我们要做乘法向量res(r,0);for(int i=0;i<r;i++){for(int j=0;j<r;j++){res[(i+j)%r]+=(p1[i]*p2[j]);}}返回res[0];我以前已经实现了这一部分,如果你还对一些事情感兴趣,请告诉我。我更希望您自己实现代码,但如果您需要代码,请告诉我。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 使用动态编程计算二项式系数
- 如何通过素数计算非常大的二项式系数模
- 如何计算等距二项式系数的和
- 整数计算的二项式系数使用boost::math::binomial_coefficient,返回值为boost::mul