Java 由前n个自然数的二进制表示形式连接而成的数字的十进制值
给定一个数字n,找出由前n个自然数的二进制表示形式串联而成的数字的十进制值。Java 由前n个自然数的二进制表示形式连接而成的数字的十进制值,java,math,binary,mod,Java,Math,Binary,Mod,给定一个数字n,找出由前n个自然数的二进制表示形式串联而成的数字的十进制值。 以10^9+7为单位打印答案 此外,n可以大到10^9,因此需要对数时间方法 例:n=4,答案=220 解释:形成的编号=11011100(1=1,2=10,3=11,4=100)。 11011100=“220”的十进制值 下面我使用的代码只适用于第一个整数N注意,使用字符串表示法是不必要的(而且,在任务更改后也不有用)。看看位算术的方法(Python,但原理是一样的) 在关于模100000007的新条件下,我们只需在
以10^9+7为单位打印答案 此外,n可以大到10^9,因此需要对数时间方法 例:n=
4
,答案=220
解释:形成的编号=11011100
(1=1
,2=10
,3=11
,4=100
)。
11011100
=“220”
的十进制值
下面我使用的代码只适用于第一个整数N注意,使用字符串表示法是不必要的(而且,在任务更改后也不有用)。看看位算术的方法(Python,但原理是一样的) 在关于模100000007的新条件下,我们只需在每一步的结果计算行中添加模运算,因为左移和/或ing相当于2的幂乘和加法,这些运算遵循模性质的等价关系。请注意,中间结果不超过
100000007*n
,因此long类型适用于合理的n值
n = 100
size = 0 #bit length of addends
result = 0 # long accumulator
for i in range(1, n + 1):
if i & (i - 1) == 0: #for powers of two we increase bit length
size += 1
result = ((result << size) | i) % 1000000007 #shift accumulator left and fill low bits with new addend
print(result)
请注意,不需要使用字符串表示法(此外,在任务更改后也不有用)。看看位算术的方法(Python,但原理是一样的) 在关于模100000007的新条件下,我们只需在每一步的结果计算行中添加模运算,因为左移和/或ing相当于2的幂乘和加法,这些运算遵循模性质的等价关系。请注意,中间结果不超过
100000007*n
,因此long类型适用于合理的n值
n = 100
size = 0 #bit length of addends
result = 0 # long accumulator
for i in range(1, n + 1):
if i & (i - 1) == 0: #for powers of two we increase bit length
size += 1
result = ((result << size) | i) % 1000000007 #shift accumulator left and fill low bits with new addend
print(result)
cin>>n;
ll-ans=1;
ll 1=1;
对于(inti=2;icin>>n;
ll-ans=1;
ll 1=1;
对于(int i=2;i,这个问题需要O(N)
时间。幸运的是,这可以在O(logN)
时间内解决。另外,这是顺序:
1,6,27,220,1765,14126,113015,1808248,28931977, 462911642,7406586283,118505380540,1896086088653, 30337377418462,485398038695407,15532737238253040, 497047591624097297,15905522931971113522
顺序遵循此递归关系:
哪里⌊.⌋ 是
a(n)
也可以表示为倍数之和
如果我们对a(14)
感兴趣,下面是它的计算方法
将上述方程两边的二次幂相乘,得到如下方程:
如果我们加上以上所有的方程,a(14)
可以表示为四个
算术-几何级数之和。
需要注意的是,在除第一个序列外的所有序列中,算术级数的第一项是形式的,最后一项是形式的
算术-几何序列的n项之和可使用以下公式计算:
由于我们感兴趣的是a(n)mod 100000007
,而不是实际的a(n)
,这些模运算可能会派上用场
对于需要一些数论基础知识的除法模来说,这是一个很好的起点
一旦我们计算出所需序列的数量以及每个序列的五个变量a、n、d、b、r
,就可以在O(logn)
时间内计算出模100000007的a(n)
下面是一个正在运行的C++
代码:
#include <numeric>
#include <iostream>
#define mod long(1e9+7)
long multiply(long a,long b){
a%= mod;b%= mod;
return (a*b)%mod;
}
void inverseModulo(long a,long m,long *x,long *y){ //ax congruent to 1 mod m
if(!a){
*x=0;
*y=1;
return ;
}
long x1,y1;
inverseModulo(m%a,a,&x1,&y1);
*x=y1-(m/a)*x1;
*y=x1;
return;
}
long moduloDivision(long a,long b,long m){ // (a*(returnValue))mod m congruent to b mod m
//https://www.geeksforgeeks.org/modular-division/ and https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
long x,y;
inverseModulo(b, m, &x, &y);
x%=m;
return (x*a)%m;
}
long power(long n,long r){ //calculates (n^r)%mod in logarithmic time
if(r==0) return 1;
if(r==1) return n;
if(r%2){
auto tmp=power(n, (r-1)/2);
return multiply(multiply(n,tmp),tmp);
}
auto tmp=power(n, r/2);
return multiply(tmp, tmp);
}
long sumOfAGPSeries(long a,long d,long b,long r,long n){
if(r==1) return multiply(n, multiply(a, 2)+multiply(n-1, d))/2;
long left=multiply(multiply(d, r), power(r,n-1)-1);
left=a+moduloDivision(left,r-1,mod);
left=multiply(left, b);
left%=mod;
long right=multiply(multiply(b, power(r, n)), a+multiply(n-1, d));
long ans=right-left;
ans=(ans%mod + mod) % mod;
return moduloDivision(ans,r-1,mod);
}
signed main(){
long N=1000;
long ans = 0;
long bitCountOfN = log2(N) + 1;
long nearestPowerOfTwo = pow(2, bitCountOfN - 1);
long startOfGP = 0;
while (nearestPowerOfTwo) { // iterating over each arithmetico–geometric sequence
long a, d, b, r, n;
a = N;
d = -1;
b = power(2, startOfGP);
r = power(2, bitCountOfN);
n = N - nearestPowerOfTwo + 1;
ans += sumOfAGPSeries(a, d, b, r, n);
ans %= mod;
startOfGP += n * bitCountOfN;
N = nearestPowerOfTwo - 1;
nearestPowerOfTwo >>= 1;
bitCountOfN--;
}
std::cout << ans << std::endl;
return 0;
}
def a(n):
return int("".join([(bin(i))[2:] for i in range(1, n+1)]), 2)
for n in range(1,100):
print (a(n)%1000000007)
这个问题需要O(N)
时间。幸运的是,这可以在O(logN)
时间内解决。另外,这是顺序:
1,6,27,220,1765,14126,113015,1808248,28931977, 462911642,7406586283,118505380540,1896086088653, 30337377418462,485398038695407,15532737238253040, 497047591624097297,15905522931971113522
顺序遵循此递归关系:
哪里⌊.⌋ 是
a(n)
也可以表示为倍数之和
如果我们对a(14)
感兴趣,下面是它的计算方法
将上述方程两边的二次幂相乘,得到如下方程:
如果我们加上以上所有的方程,a(14)
可以表示为四个
算术-几何级数之和。
需要注意的是,在除第一个序列外的所有序列中,算术级数的第一项是形式的,最后一项是形式的
算术-几何序列的n项之和可使用以下公式计算:
由于我们感兴趣的是a(n)mod 100000007
,而不是实际的a(n)
,这些模运算可能会派上用场
对于需要一些数论基础知识的除法模来说,这是一个很好的起点
一旦我们计算出所需序列的数量以及每个序列的五个变量a、n、d、b、r
,就可以在O(logn)
时间内计算出模100000007的a(n)
下面是一个正在运行的C++
代码:
#include <numeric>
#include <iostream>
#define mod long(1e9+7)
long multiply(long a,long b){
a%= mod;b%= mod;
return (a*b)%mod;
}
void inverseModulo(long a,long m,long *x,long *y){ //ax congruent to 1 mod m
if(!a){
*x=0;
*y=1;
return ;
}
long x1,y1;
inverseModulo(m%a,a,&x1,&y1);
*x=y1-(m/a)*x1;
*y=x1;
return;
}
long moduloDivision(long a,long b,long m){ // (a*(returnValue))mod m congruent to b mod m
//https://www.geeksforgeeks.org/modular-division/ and https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
long x,y;
inverseModulo(b, m, &x, &y);
x%=m;
return (x*a)%m;
}
long power(long n,long r){ //calculates (n^r)%mod in logarithmic time
if(r==0) return 1;
if(r==1) return n;
if(r%2){
auto tmp=power(n, (r-1)/2);
return multiply(multiply(n,tmp),tmp);
}
auto tmp=power(n, r/2);
return multiply(tmp, tmp);
}
long sumOfAGPSeries(long a,long d,long b,long r,long n){
if(r==1) return multiply(n, multiply(a, 2)+multiply(n-1, d))/2;
long left=multiply(multiply(d, r), power(r,n-1)-1);
left=a+moduloDivision(left,r-1,mod);
left=multiply(left, b);
left%=mod;
long right=multiply(multiply(b, power(r, n)), a+multiply(n-1, d));
long ans=right-left;
ans=(ans%mod + mod) % mod;
return moduloDivision(ans,r-1,mod);
}
signed main(){
long N=1000;
long ans = 0;
long bitCountOfN = log2(N) + 1;
long nearestPowerOfTwo = pow(2, bitCountOfN - 1);
long startOfGP = 0;
while (nearestPowerOfTwo) { // iterating over each arithmetico–geometric sequence
long a, d, b, r, n;
a = N;
d = -1;
b = power(2, startOfGP);
r = power(2, bitCountOfN);
n = N - nearestPowerOfTwo + 1;
ans += sumOfAGPSeries(a, d, b, r, n);
ans %= mod;
startOfGP += n * bitCountOfN;
N = nearestPowerOfTwo - 1;
nearestPowerOfTwo >>= 1;
bitCountOfN--;
}
std::cout << ans << std::endl;
return 0;
}
def a(n):
return int("".join([(bin(i))[2:] for i in range(1, n+1)]), 2)
for n in range(1,100):
print (a(n)%1000000007)
您的值太大,无法存储在
Integer
中。请尝试更大的对象类,如Long
。如果您想要无界缩放,请使用biginger
。当更改为Long时,它将一直工作到18个整数返回新的biginger(输入,2);
您的值太大,无法存储在整数中。请尝试更大的对象类,如Long
。如果您想要无界缩放,请使用biginger
。当更改为Long时,它将一直工作到18个整数返回新的biginger(输入,2)
既然连接很大,我们可以使用模10^9+7吗?这个条件彻底改变了问题。编辑问题是值得的。是的,我编辑了答案,检查结果是否与长算术一致。@MBo由于约束非常大,这种O(N)方法不可伸缩。存在O(logN) approach@duplex143但是作者并没有提到n约束,所以我不理解DV的原因,因为连接很大,我们可以使用模10^9+7吗?这个条件彻底改变了问题。值得编辑quest