Codeforces Round #515 (Div. 3) E(模擬+字首和)
阿新 • • 發佈:2018-11-08
題意: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; }