标签:res 技巧 const std efi ++ ace open 注意
[http://codeforces.com/contest/1066/problem/E]
给你长度分别为n,m的二进制串,当b>0时,对a,b,&运算,然后b右移一位,把每次a&b的10进制结果累加对 998244353取余
模拟这个过程,但有个技巧就是对b从高位开始求二进制的前缀和
具体看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
const ll N=2e5+10;
ll one[N],pw[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll i,j,k,n,m;
string a,b;
//freopen("in.txt","r",stdin);
cin>>n>>m;
cin>>a>>b;
//使位数一致在位数少的前面加0
if(n<m){
a=string(m-n,‘0‘)+a;
}
else if(m<n){
b=string(n-m,‘0‘)+b;
}
n=max(n,m);
one[0]=(b[0]==‘1‘);
for(i=1;i<n;i++) one[i]=one[i-1]+(b[i]==‘1‘);//b高位开始的前缀和
pw[0]=1;
for(i=1;i<N;i++) pw[i]=pw[i-1]*2ll%mod;//计算2的幂次预处理
ll ans=0;
for(i=0;i<n;i++){
ll res=(a[i]==‘1‘);
res=res*pw[n-i-1]%mod;//计算a这个位置的10进制值
ans=(ans+res*one[i]%mod)%mod;//之所以*one[i],是因为b右移的过程,a[i]对应的次数就是b高位开始的前缀和,注意取余mod
}
cout<<ans<<endl;
return 0;
}
标签:res 技巧 const std efi ++ ace open 注意
原文地址:https://www.cnblogs.com/mch5201314/p/9786026.html