C++ 求从1到n的数的所有二进制展开式之和
最近,我在一个竞争网站上遇到了一个问题,这是一个挑战。在那里,它被要求找出从1到n的数字的二进制表示的所有十进制解释的总和。假设当n=4时,总和为1+10+11+100=122。因为这个数字可能非常大,所以答案应该是模100000007。 我遇到了以下解决方案,但无法对其进行优化C++ 求从1到n的数的所有二进制展开式之和,c++,binary,C++,Binary,最近,我在一个竞争网站上遇到了一个问题,这是一个挑战。在那里,它被要求找出从1到n的数字的二进制表示的所有十进制解释的总和。假设当n=4时,总和为1+10+11+100=122。因为这个数字可能非常大,所以答案应该是模100000007。 我遇到了以下解决方案,但无法对其进行优化 #include<iostream> #include<queue> using namespace std; int Mod(string s, int a) { int res =
#include<iostream>
#include<queue>
using namespace std;
int Mod(string s, int a)
{
int res = 0, i, l = s.size();
for( i = 0 ; i < l ; i++ )
{
res = ( res * 10 + s[i] - '0' ) % a;
}
return res;
}
int main()
{
int t;
cin >> t;
while(t--)
{
long long n;
cin >> n;
int Sum = 0, mod = 1000000007;
queue<string> q;
q.push("1");
while( n > 0 )
{
n--;
string s1 = q.front();
q.pop();
Sum = ( Sum + Mod(s1, mod) ) % mod;
string s2 = s1;
q.push(s1.append("0"));
q.push(s2.append("1"));
}
cout << Sum << endl;
}
return 0;
}
#包括
#包括
使用名称空间std;
整数模(字符串s,整数a)
{
int res=0,i,l=s.size();
对于(i=0;i>t;
而(t--)
{
长n;
cin>>n;
整数和=0,模=100000007;
队列q;
q、 推送(“1”);
而(n>0)
{
n--;
字符串s1=q.front();
q、 pop();
Sum=(Sum+Mod(s1,Mod))%Mod;
字符串s2=s1;
q、 push(s1.append(“0”));
q、 推送(s2.附加(“1”));
}
cout在做了一些计算后,我终于想出了解决方案。感谢@maximum_prime_is_463035818提供了这些提示。以下是我的代码:
#include<iostream>
#include<cmath>
#define mod 1000000007
using namespace std;
long long power(long long x, long long y)
{
long long res = 1LL;
while(y)
{
if( y & 1LL )
{
res = ( res * x ) % mod;
}
y >>= 1LL;
x = ( x * x ) % mod;
}
return res;
}
int main()
{
long long t;
cin >> t;
while(t--)
{
long long n, i, l, m, s = 0;
cin >> n;
if( n && (!( n & ( n - 1LL ) )) )
{
l = ceil(log2(n)) + 1LL;
}
else
{
l = ceil(log2(n));
}
for( i = 0LL ; i < l ; i++ )
{
if( n & ( 1LL << i ) )
{
m = ( ( ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) ) + 1LL ) + ( ( n % ( 1LL << ( i + 1LL ) ) ) % ( 1LL << i ) ) );
}
else
{
m = ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) );
}
s = ( s + ( ( ( m % mod ) * power(10, i) ) % mod ) ) % mod;
}
cout << s << endl;
}
return 0;
}
#包括
#包括
#定义mod 100000007
使用名称空间std;
长功率(长x、长y)
{
长res=1L;
while(y)
{
如果(y&1LL)
{
res=(res*x)%mod;
}
y>>=1LL;
x=(x*x)%mod;
}
返回res;
}
int main()
{
长t;
cin>>t;
而(t--)
{
长n,i,l,m,s=0;
cin>>n;
如果(n&(!(n&(n-1LL)))
{
l=ceil(log2(n))+1L;
}
其他的
{
l=ceil(log2(n));
}
对于(i=0LL;i 如果(n&(1LL)你想优化什么?运行时?内存使用?可读代码?我忘了提到时间限制。我已经编辑了它。它是1秒。因此,很明显,它是运行时。正确的解决方案不涉及实际相加,而是一个简单的数学公式。那就是“竞争网站”只是一个基于随机编程或数学技巧的无意义拼图列表。如果你不知道什么是你无法解决的诀窍。不幸的是,那些竞争性的网站不提供C++或编程指导,它们可以教你解决谜题所需的技巧。如果有人真的想学习C++,那就只有W。是的,他们会用一个。@Shashank实际上,这是数字二进制表示法的十进制解释之和。10
在你的例子中,不是二的二进制表示法,而是十的十进制表示法。然后你需要更仔细地思考;)。当n
为例如15
时,则有15/2
个数具有第一个位集,15/4
个数具有第二个位集……诀窍就是迭代2
的幂,而不是迭代1
到n