题目链接:https://www.zhixincode.com/contest/25/problem/C?problem_id=361
将题目所求转换成
然后分别求一下Fib的前n项和 就是 Fib(n+2)-1
和lowbit( F(n) ) 的前n项和
打表观察lowbit的数据可以看出:
1.%3不为0的时候全部为1
2.%3为0的时候 若n是奇数,全部为2
3.%3为0的时候 若n是偶数,1/2是8,1/4是16......
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
typedef long long ll;
using namespace std;
const int mod=998244353 ;
struct mat
{
ll a[2][2];
mat()
{
memset(a,0,sizeof(mat));
}
};
mat multiple(mat x,mat y)
{
mat res;
memset(res.a,0,sizeof(res.a));
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
res.a[i][j]=((res.a[i][j]%mod)+((x.a[i][k]*y.a[k][j])%mod))%mod;
}
}
}
return res;
}
ll quick_pow(ll n)
{
n-=2;
mat base,res;
base.a[0][0]=1;
base.a[0][1]=1;
base.a[1][0]=1;
base.a[1][1]=0;
for(int i=0;i<2;i++)
{
res.a[i][i]=1;
}
while(n)
{
if(n&1)
{
res=multiple(res,base);
}
base=multiple(base,base);
n=n>>1;
}
return (res.a[0][0]+res.a[0][1])%mod;
}
ll quick_mul(ll a,ll b)//类比快速幂
{
ll res=0;
while(b)
{
if(b&1)
{
res=(res+a)%mod;
}
a=(a+a)%mod;
b=b>>1;
}
//cout<<"fuck"<<endl;
return res;
}
int main()
{
ios::sync_with_stdio(false);
ll n,t;
cin>>t;
while(t--)
{
cin>>n;
ll ans=quick_pow(n+2)-1;
ans=((ans-(n/3*2+n%3))%mod+mod)%mod;//%3不为0的部分全部为1
n/=3;//%3==0的数量
ans=((ans-((n/2+n%2)*2))%mod+mod)%mod;//%3为0且为奇数的情况全部为2
for(int i=1;i<=62;i++)//为偶数的情况
{
ll now=n/(1ll<<i);//当前的总数(8的情况是n的一半向下取整)
if(now)
{
ll cnt=now/2+now%2;//8占当前总数的一半(向上取整)
ans=(ans-quick_mul(cnt,1ll<<(i+2))+mod)%mod;
//cout<<"ans:"<<ans<<endl;
}
}
cout<<ans<<endl;
}
return 0;
}