专栏文章
不卡单 log 这一块
CF1423J题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min1rgl4
- 此快照首次捕获于
- 2025/12/01 19:09 3 个月前
- 此快照最后确认于
- 2025/12/01 19:09 3 个月前
我还寻思这题怎么是个 *2400 呢,合着我的做法就不是预期解啊。
注意到 ,考虑二进制。
对于 项,其对于第 至 位的贡献为 ,而对于第 位,第 位和第 位的贡献可以在 中任选,且互相独立。
因此,考虑从低到高讨论每一位。每一位最多有 个互相独立的数作出贡献。记 表示考虑低 位,且在第 位上遗留进位为 的方案数。可以得到 为不超过 的自然数。
对于 ,有 ,,。对于 ,若 这一位上是 ,则两种可能的方案为两个位置均填 或填 。前者不进位,后者进 位,故 ,,。若 这一位上是 ,则这两个位置上必须一个 一个 ,故 ,,。
对于后面的位置,若 这一位上是 ,则 (全部填 ),(分别为两个填 ,一个填 ,不填 ),。(分别为都填 和填两个 )。否则, (分别为填一个 和不填 ),(分别为填三个 ,填两个 和填一个 ),(都填 )。
记 的最高位为 ,则最后取 极为答案。
时间复杂度 。
CPP#include<bits/stdc++.h>
using namespace std;
const int Maxw=63,mod=1000000007;
int T;
long long m;
long long dp[Maxw+3][3],ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>T;
while(T--)
{
cin>>m;
if(m==1)
{
cout<<1<<"\n";
continue;
}
dp[0][0]=1;
if((m>>1)&1) dp[1][0]=2,dp[1][1]=0,dp[1][2]=0;
else dp[1][0]=1,dp[1][1]=1,dp[1][2]=0;
ans=dp[1][0];
for(int i=2;(1ll<<i)<=m;i++)
{
if((m>>i)&1)
{
dp[i][0]=(dp[i-1][0]*3+dp[i-1][1])%mod;
dp[i][1]=(dp[i-1][0]+dp[i-1][1]*3+dp[i-1][2]*3)%mod;
dp[i][2]=dp[i-1][2];
}
else
{
dp[i][0]=dp[i-1][0];
dp[i][1]=(dp[i-1][0]*3+dp[i-1][1]*3+dp[i-1][2])%mod;
dp[i][2]=(dp[i-1][1]+dp[i-1][2]*3)%mod;
}
ans=dp[i][0];
}
cout<<ans<<"\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...