1. 程式人生 > >codeforces 1066 E. Binary Numbers AND Sum

codeforces 1066 E. Binary Numbers AND Sum

題目連結:http://codeforces.com/problemset/problem/1066/E 題目大意:給你兩個二進位制串a和b,長度分別為n, m;然後執行下面的步驟: 1)如果b等於0,執行3),否則執行 2) 2)計算a&b ,得出一個結果si,b除以2。執行 1)。 3)計算所有的si的和。 計算結果對指定數求餘。輸出結果。 題解思路:a是不會改變的,b會變小(二進位制長度減小)。我們可以想到對於b中某個位置bi和bj(假設i<j,且i,j < min(n,m) )。剛開始bj會和aj與運算,後面由於b的右移,所以bi的位置會向右移動,也就總會存在bi和aj與運算。也就是說對於aj,aj會和所有的bi進行與運算(其中i 滿足i <= j)。想明白了這點就是對任何位置的字首累加求和了。 注意:我程式碼中的儲存二進位制串的順序和題解中順序不一致,所以你們需要自己理解一下。

程式碼:

#include <iostream>

using namespace std;
#define ll long long
#define mod 998244353
#define rep(i,a,n) for(int i=n;i>=a;i--)
int main()
{
    int n,m,a[200005],b[200005];
    cin>>n>>m;
    for(int i = 1;i <= 200001; i++)b[i] = 0, a[i] = 0;
    rep(i,1,n){char c;cin>>c;a[i] = c-48;}
    rep(i,1,m){char c;cin>>c;b[i] = c-48;}
    rep(i,1,m){b[i] += b[i+1];}
    ll ans = 0, w = 1;
    for(int i = 1; i <= n; i++){
        ans += a[i]*b[i]*w;
        ans %= mod;
        w *= 2;
        w %= mod;
    }
    cout<<ans;
    return 0;
}