题意
数对 (x,y) 是好的,当且仅当 x⊕y=x | y,其中 ⊕ 表示异或操作,| 表示或运算。
给定正整数 N,请你求解有多少个好的数对 (x,y),满足 x,y∈[0,N]。
因为出题人小 M 比较仁慈,所以 N 将以二进制的形式给出。
答案对 998244353 取模。
Input
输入共 1 行,包含一个正整数 N,通过二进制的形式给出。
评测数据规模:
对于所有测评数据,1≤N<21234567。
Output
输出共 1 行,输出 1 个整数,表示最终答案,答案对 998244353 取模。
Sample Input
111
Sample Output
27
状态表示:
f [ i ] f[i] f[i]表示设整数 X X X,其二进制等于 N N N的最高的 i i i位,在 [ 0 , X ] [0,X] [0,X]区间内的合法数对数量
状态转移
从最高位到最低位遍历
N
N
N,当第
i
+
1
i+1
i+1位等于
0
0
0时
f
[
i
+
1
]
=
f
[
i
]
∗
3
f[i+1]=f[i]*3
f[i+1]=f[i]∗3;
当第
i
+
1
i+1
i+1位等于
0
0
0时
f
[
i
+
1
]
=
f
[
i
]
∗
3
−
c
n
t
不合法数对
f[i+1]=f[i]*3-cnt_{不合法数对}
f[i+1]=f[i]∗3−cnt不合法数对;其中
c
n
t
不合法数对
cnt_{不合法数对}
cnt不合法数对等于
2
∗
2
c
n
t
0
2*2^{cnt0}
2∗2cnt0,
c
n
t
0
cnt0
cnt0等于
N
N
N的最高
i
i
i位零的数量;
代码
#include <iostream>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <cstring>
#include <vector>
#define ll long long
#define x first
#define y second
#define pb push_back
#define PII pair<long long,long long>
#define debug(x) cout << endl << "debug=" << x << endl << endl
//#define endl '\n'
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int N = 2e6+10;
const double PI=acos(-1.0);
const double eps=1e-9;
using namespace std;
const ll MOD=998244353;
int a[N],len=0,cnt0=0;
ll ans=3;
ll qmi(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=res*a%MOD;
a=a*a%MOD;
b>>=1;
}
return res;
}
void solve(){
string s;
cin>>s;
for(int i=0;i<s.size();i++){
a[++len]=s[i]-'0';
}
for(int i=2;i<=len;i++){
ans=ans*3%MOD;
if(a[i]==0){
ans=(ans-qmi(2,cnt0)*2)%MOD;
cnt0++;
}
}
cout<<(ans+MOD)%MOD<<endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;
T=1;
while(T--){
solve();
}
return 0;
}