题意:a和b是两个01字符串,现要计算a&b+a&b>>1+a&b>>2+……(直到b=0)
思路: 因为a和b的长度不确定,所以给短的那个在前面补上0,因为b每一次往右移,所以可以计算b的每一位上的贡献,这个贡献就是这一位及前面一共有多少1,为什么呢?考虑a=1001和b=10101,那么a的第四位一共要&三次b的1,值为1,所以答案就是每一位十进制的值*这一位的贡献,注意用前缀和预处理一下b的1的个数。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=200005;
const int mod=998244353;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qpow(ll a,ll b){ll t=1;while(b){if(b%2){t=(t*a)%mod;b--;}a=(a*a)%mod;b/=2;}return t;}
int main()
{
std::ios::sync_with_stdio(false);
int n,m;
string a,b;
while(cin>>n>>m)
{
cin>>a>>b;
if(n<m)
{
a=string(m-n,'0')+a;
}
else
{
b=string(n-m,'0')+b;
}
n=max(n,m);
ll sum[maxn]={0};
sum[0]=(b[0]=='1');
for(int i=1;i<n;i++)
{
sum[i]=sum[i-1]+(b[i]=='1');
}
ll ans=0;
for(int i=0;i<n;i++)
{
ll res=(a[i]=='1');
if(res)
res=qpow(2,n-i-1);
ans=(ans+(res*sum[i])%mod)%mod;
}
cout<<ans<<endl;
}
return 0;
}