求
\[\sum_{i=0}^{2^{n}}{lowbit(i)} \]
\((n≤10^{18})\)答案对998244353取模
lowbit
首先数组数组里经常出现的lowit函数
对于lowbit
给定非负整数n。记lowbit(x)为x的二进制表示下最低位的1所对应的值
比如
lowbit(1),1的二进制位1,最低为对应的是1
lowbit(3),3的二进制为11,最低位对应的是1
lowbit(4),4的二进制为100,最低位对应的是4
一般来说2^n的lowbit为本身,奇数的lowbit为1
比如n=2
\(\sum_{i=0}^{2^{n}}{lowbit(i)}\\ = \sum_{i=0}^{4}{lowbit(i)}\\ = lowbit(0) + lowbit(1)+ lowbit(2)+ lowbit(3)+ lowbit(4)\)
而对于\(lowbit(0)=0,lowbit(2^{n})=2^{n}\)
而对于\(2^{n}有2^{n-1}个奇数\)
所以式子变成了求
\(lowbit(2) + lowbit(4) +lowbit(6).....+lowbit(2^{n-1})+2^{n}+2^{n-1}\)
\(令x=lowbit(2) + lowbit(4) +lowbit(6).....+lowbit(2^{n-1})\)
打表
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <vector>
#define ll long long
using namespace std;
const int mod = 998244353;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return f*x;
}
ll lowbit(ll x){
return (x&(-x)) % mod;
}
ll quickpow(ll a,ll b){
ll ans = 1;
while(b){
if(b&1) ans = ans * a % mod;
b >>= 1;
a = a * a%mod;
}
return ans;
}
void debug(){
for(ll n = 1; n <= 20; n++){
ll all = quickpow(2,n);
ll ans = 0;
for(ll j = 1;j <= all; j++){
ans = (ans + lowbit(j)) % mod;
}
cout<<n<<" "<<ans<<" "<<ans-all-all/2<<endl;
}
}
int main(){
debug();
return 0;
}
打表发现规律
n x
1 0
2 2
3 8
4 24
5 64
6 160
7 384
8 896
9 2048
10 4608
11 10240
12 22528
13 49152
14 106496
15 229376
16 491520
17 1048576
18 2228224
19 4718592
20 9961472
推导
发现\(a_{n+1}=2a_{n}+2^{n}\)
所以理由生成函数解
\(a_{n+1}-2a_{n} = 2^{n}\)
①求齐次
\(a_{n+1}-2a_{n} = 0\)
$ x-2=0 \(解得\)x=2\(,所以通解为\)c_{1}2^{n}$
②求非齐次
\(x=2\)为1重根且等于常数,所以特解为\(Pn2^{n}\)
代入非齐次\(P(n+1)2^{n+1}=2Pn2^{n}+2^{n}\)
解得\(P=\frac{1}{2}\)
特解为\(n2^{n-1}\)
③求解
解为齐次通解+非齐次特解
\(x =c_{1}2^{n}+ n2^{n-1} ,其中n=1时,x=0\)
\(c_{1}=-\frac{1}{2}\)
\(x = (n-1)2^{n-1}\)
与上面合并得到
\(a_{n} = (n-1)2^{n-1}+2^{n}+2^{n-1} = (n+2)2^{n-1}\)
\(∴a_{n} = (n+2)2^{n-1}\)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define ll long long
#define mod 998244353
using namespace std;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
ll pow(ll a,ll b,ll p){
ll ans = 1;
while(b){
if(b&1)ans = ans * a % p;
b >>= 1;
a = a * a %p;
}
return ans;
}
void getans(ll n){
if(n == 0)cout<<"1"<<endl;
else{
ll ans = ((n + 2) % mod) * (pow(2,n-1,mod) %mod) %mod;
cout<<ans<<endl;
}
}
int main(){
ll t = read();
while(t--){
ll n = read();
getans(n);
}
return 0;
}