/*
无关的元素:
对于给定的n个数a1,a2,...,an,依次求出相邻两数之和,将得到一个新数列。重复上述操作,最后记过将变成一个数。问这个数除以m的余数与哪些数无关?
例如n=3,m=2时,第一次求和得到a1+a2,a2+a3,再求和得到a1+2a2+a3,它除以2的余数和a2无关。1<=n<=10^5,2<=m<=10^9
分析:
最后的求和式是a1,a2,...,an的线性组合。设ai的系数为f(i),则和式除以m的余数与ai无关当且仅当f(i)是i的倍数。
a1 a2 a3 a4 a5
a1+a2 a2+a3 a3+a4 a4+a5
a1+2a2+a3 a2+2a3+a4 a3+2a4+a5
a1+3a2+3a3+a4 a2+3a3+3a4+a5
a1+4a2+6a3+4a4+a5
上述式子类似杨辉三角,5个数最后结果类似第5行的杨辉三角式子
所以由n行,得出杨辉三角第n行系数,再除以m即可
分析:
ai的系数是C上i-1下n-1,问题变成了C上0下n-1,C上1下n-1,...,C上n-1下n-1中有哪些是m的倍数。
由于C上i-1下n-1太大,必须用高精度才能存。我们关心哪些是m的倍数,只需计算m的唯一分解式中各个素因子在C上i-1下n-1中的指数。
这些指数可用C上k下n = (n-k+1)/k*C上k-1下n-1递推。
输入:
3 2
5 4
输出:
2
2 4
*/
#include <stdio.h>
void yanghuiFactor(int n,int m)
{
n--;
int iArr[10000];
iArr[0] = 1;
for(int i = 1 ; i <= n; i++)
{
iArr[i] = iArr[i-1]*(n-i+1)/i;//注意这里,杨辉三角第n行共有n+1个数,因此你所谓的n个数,起始是第n-1行杨辉三角中的系数
}
bool isFirst = true;
for(int i = 0 ; i <= n; i++)
{
if(iArr[i] % m == 0)
{
if(!isFirst)
{
printf(" %d",i+1);
}
else
{
printf("%d",i+1);
isFirst = false;
}
}
}
printf("\n");
}
void process()
{
int n,m;
while(EOF != scanf("%d %d",&n,&m))
{
yanghuiFactor(n,m);
}
}
int main(int agrc,char* argv[])
{
process();
getchar();
return 0;
}
算法竞赛入门经典:第十章 数学概念与方法 10.7无关的元素
最新推荐文章于 2021-04-28 12:27:15 发布