使用K颜色的不同项链数量 我有一个任务,用C++中的K颜色找到不同项链的数量。
如果其中一条项链 无法通过旋转第二条项链从第二条项链获得 任何角度的项链。 求不同项链的总数(10^9+7) 我认为这个公式很好地解决了一个问题: 我用C++实现了一个程序:使用K颜色的不同项链数量 我有一个任务,用C++中的K颜色找到不同项链的数量。,c++,algorithm,math,combinatorics,C++,Algorithm,Math,Combinatorics,如果其中一条项链 无法通过旋转第二条项链从第二条项链获得 任何角度的项链。 求不同项链的总数(10^9+7) 我认为这个公式很好地解决了一个问题: 我用C++实现了一个程序: #include <algorithm> #include <iostream> #include <cmath> using namespace std; const int M = 1e9 + 7; int main() { long long n, k; ci
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int M = 1e9 + 7;
int main()
{
long long n, k;
cin >> n >> k;
long long x = 0;
for (int i = 0; i < n; ++i) {
x += pow(k, __gcd(i,n));
}
cout << (int)(((double)1/n) * x) % M;
return 0;
}
#包括
#包括
#包括
使用名称空间std;
常数int M=1e9+7;
int main()
{
长n,k;
cin>>n>>k;
长x=0;
对于(int i=0;i cout对不起,如果您的公式不正确,我们无能为力,但这是您的公式的正确实现方式
在您的代码中,循环变量i
与公式不同。您正在移动i=0,…,n-1
,但公式显示i=1,2,….n
更新:我认为你的行x+=pow(k,u gcd(I,n));
不太正确。当x+pow(k,u gcd(I,n))
将大于10^9+7时,你应该取模,但你没有这样做
为了让代码更清楚,模运算是分布在+
上的,因此您可以编写
( a + b ) % c = ( ( a % c ) + ( b % c ) ) % c
但是,模
不是分布在/
上的,所以不能只写
( a / b ) % c = ( ( a % c ) / ( b % c ) ) % c
要计算(x/y)%M
,您必须计算
(x * MMI(y)) % M
感谢@ivlad指出MMI缺陷:)
改变
for (int i = 0; i < n; ++i) {
x += pow(k, __gcd(i,n));
}
cout << (int)(((double)1/n) * x) % M;
for(int i=0;iMOD)x%=MOD;
}
y=(y*y);
如果(y>MOD)y%=MOD;
b/=2;
}
返回x;
}
长-长修改(长n,长m){
返回功率(n,m-2,m);
}
int main()
{
长n,k;
cin>>n>>k;
对于(长i=1;i考虑数字限制
long-long
可以是unsigned long-long
甚至long-double
double
可以是长double
。这实际上取决于平台,但可能是原因
顺便说一句,n
被定义为long
,它真的会那么大吗?如果是的话,你的循环将花费很长时间,你可能会“超过时间限制”。如果没有,只需声明它int
。声明它long
而int
就足够了,可能会导致一些错误!!我发现您的程序有两个问题。第一个问题是pow
即使是k
和n
的小值也会溢出。这取决于输入的大小(你没有给出),pow
甚至在你取模之前就可能溢出。你应该用你自己的powModM
替换pow
,它更频繁地取%M
。比如
int powModM(int k, int n, int M) {
int res = 1;
for (int i = 0; i < n; ++i) {
res = (res * k) % M;
}
return res;
}
实际上,你的公式是不正确的。正确的公式可以在这里找到:
我的实现刚刚完成。检查循环条件。与公式中的条件不匹配。您好!抱歉,没有更改:(++i
不会做您认为它会做的事情。具体来说,for循环条件总是先计算初始值,然后计算终止值,然后计算递增值。因此,无论您是在for循环中编写++i
还是i++
,都无关紧要。但由于++i
可能会误导人们认为循环正在做其他事情始终建议使用i++
作为正在发生的事情的自我记录提醒。当前的所有答案很可能都是错误的,因为x
在for循环后可能会超过偶数long
,即使n
小到63
和k
小到2
。模为t这里有一个原因:你必须在每一步计算它。@ SyBeMeN-UH,相反的是。在C++中总是使用<代码> ++i < /> >而不是<代码> i++< /> >。原因是后者有时比前者慢——不是内置的类型,如代码> int <代码>,而是自定义类型。无论如何,它们的语义在这里是相同的。我看不出有什么会让人困惑……嗨!谢谢,我在代码中修复了它,但没有任何改变!解决方案再次通过了一半的测试用例。哦,我有一个错误file.cc:18:49:error:binary expression的操作数无效('typename enable_if::type'(aka'double')x=((x%M)+(pow(k,u gcd(I,n)%M))%M;
。我在这里删除了最后一个%M
,但通过了一半的测试用例。这是错误的:取模后不能除以n
,然后再取模。它会给出错误的答案。@IVlad我不知道你计算了x
模M
。然后你将结果除以n
。这就是wrong.即使n
很小,求幂运算也会导致整个东西溢出。我不理解逆。什么是参数a
和m
?a
是你的n
,m
是你的m
。
int powModM(int k, int n, int M) {
int res = 1;
for (int i = 0; i < n; ++i) {
res = (res * k) % M;
}
return res;
}
public static long inverse(long a, long m) { // mult. inverse of a mod m
long r = m;
long nr = a;
long t = 0;
long nt = 1;
long tmp;
while (nr != 0) {
long q = r/nr;
tmp = nt; nt = t - q*nt; t = tmp;
tmp = nr; nr = r - q*nr; r = tmp;
}
if (r > 1) return -1; // no inverse
if (t < 0) t += m;
return t;
}