哎…這道題一言難盡啊,從一開始的想法逾時到慢慢分析知道了字首和,在到出現了bug,電腦前一坐就是3個小時、
嘛。最近的題隻要做出來都是熬出來的…哎…越發開始懷疑人生

廢話少說,題意看樣例也能猜出來想幹什麼
如果按模拟來的話,一個一個來每次相應的10進制肯定會逾時(我也親身體驗了)
題目上說每次 b/2 ,不過其意思從樣例也可以看出隻是向右移了一位
是以我們要找個方法把每次(b >> 1 )& a 的和直接求出來。
這裡就需要一個字首和。
先看這個圖:
這是第一個樣例b每次右移的結果。
從左到右對應着二進制換成10進制的(8,4,2,1)
橫線下面的1 2 2 3 代表8 4 2 1分别有幾個。
再加上&a,這個樣例的a為1010
即 1 * 8 * 1 + 0 * 4* 2 + 1 * 2 * 2 + 0 * 1 * 3 = 8 + 0 + 4 + 0 = 12。
這樣就可以直接求出來a&b的結果。
而對于1 2 2 3的求法從下往上看和從左往右看是一樣的。也就是字首和的求法了
具體怎麼操作可以看看這裡,随便了解一下字首和還有其他好用的地方:https://blog.csdn.net/whxntj/article/details/54619204
關鍵的都講完了,其他的都很好操作了。不過有一點要注意的是,,,
哎,這個數太大了。以至于出現了一個bug耽誤了老長時間。
最後也知道原因了,什麼情況看聊天記錄吧
下面是ac代碼:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 200020;
const long mod = 998244353;
char a[maxn], b[maxn];
int prefix[maxn];
int n, m;
inline ll B_D(int j, int i)
{
ll B = 1, ans = 0;
while(i&&j)
{
ans += ((a[j--]-'0')*B*prefix[i--])%mod;
B = (B*2)%mod;
}
return ans%mod;
}
int main()
{
cin >> n >> m;
scanf("%s%s",a+1,b+1);
for(int i = 1; i <= m; ++i)
prefix[i] += prefix[i-1]+(b[i]-'0');
cout << B_D(n,m)%mod << endl;
return 0;
}