You are given two huge binary integer numbers aa and bb of lengths nn and mmrespectively. You will repeat the following process: if b>0b>0, then add to the answer the value a & ba & b and divide bb by 22 rounding down (i.e. remove the last digit of bb), and repeat the process again, otherwise stop the process.
The value a & ba & b means bitwise AND of aa and bb. Your task is to calculate the answer modulo 998244353998244353.
Note that you should add the value a & ba & b to the answer in decimal notation, not in binary. So your task is to calculate the answer in decimal notation. For example, if a=10102 (1010)a=10102 (1010) and b=10002 (810)b=10002 (810), then the value a & ba & b will be equal to 88, not to 10001000.
Input
The first line of the input contains two integers nn and mm (1≤n,m≤2⋅1051≤n,m≤2⋅105) — the length of aa and the length of bb correspondingly.
The second line of the input contains one huge integer aa. It is guaranteed that this number consists of exactly nn zeroes and ones and the first digit is always 11.
The third line of the input contains one huge integer bb. It is guaranteed that this number consists of exactly mm zeroes and ones and the first digit is always 11.
Output
Print the answer to this problem in decimal notation modulo 998244353998244353.
Examples
4 4
1010
1101
12
4 5
1001
10101
11
Note
The algorithm for the first example:
- add to the answer 10102 & 11012=10002=81010102 & 11012=10002=810 and set b:=110b:=110;
- add to the answer 10102 & 1102=102=21010102 & 1102=102=210 and set b:=11b:=11;
- add to the answer 10102 & 112=102=21010102 & 112=102=210 and set b:=1b:=1;
- add to the answer 10102 & 12=02=01010102 & 12=02=010 and set b:=0b:=0.
So the answer is 8+2+2+0=128+2+2+0=12.
The algorithm for the second example:
- add to the answer 10012 & 101012=12=11010012 & 101012=12=110 and set b:=1010b:=1010;
- add to the answer 10012 & 10102=10002=81010012 & 10102=10002=810 and set b:=101b:=101;
- add to the answer 10012 & 1012=12=11010012 & 1012=12=110 and set b:=10b:=10;
- add to the answer 10012 & 102=02=01010012 & 102=02=010 and set b:=1b:=1;
- add to the answer 10012 & 12=12=11010012 & 12=12=110 and set b:=0b:=0.
So the answer is 1+8+1+0+1=111+8+1+0+1=11.
题意:
给你两个二进制的字符串a和b。(很长)
让你进行一下操作。
把答案加上 a&b的值。然后b右移一位。
上述操作直至b==0
求最后对998244353取模后的的答案。
思路:
我们来看一下样例1。
4 4
1010
1101
我们看b,1101 从最后一位看起,最后一位的1,只能&上一次a的最后一位,然后就被消除掉了(右移)
而倒数第二位的0,无论&上多少个数(不管是0还是1) 都不会对答案做出贡献。
继续看倒数第三位的1,他会&上a中的后三位才会被消除掉,会&上a中倒数第2位的1,那么会对答案产生2的贡献。
再看b的第一位的1,他会&上a中的后四位才会被消除掉,&上a中倒数第2个的1和倒数第4位的1,会对答案产生8+2的贡献,
加起来答案就是12。
不知道大家有没有发现什么规律?
b中每一位1都会&上a中对应位置以及后面的所有位。并且b这一位的贡献值就是a中这一位以及之后的数组成的二进制数的十进制数值大小。
那么我们不妨对a进行通过快速幂取模来求出a中每一位数值的前缀和,然后b中每一位1直接去加上那么数值就是贡献。
又因为a和b可能不一样长,我们为了方便把a和b翻转后再计算。
细节见代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d ",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), ' ', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ //string a,b; int n,m; char a[maxn]; char b[maxn]; const ll mod=998244353ll; ll sum[maxn]; int main() { //freopen("D:\common_text\code_stream\in.txt","r",stdin); //freopen("D:\common_text\code_stream\out.txt","w",stdout); gbtb; cin>>n>>m; cin>>a>>b; ll x=m-n; reverse(a,a+n); reverse(b,b+m); if(a[0]=='1') { sum[0]=1ll; } for(ll i=1ll;i<max(n,m);++i) { if(a[i]=='1') { sum[i]=sum[i-1]+powmod(2ll,i,mod); sum[i]=(sum[i]+mod)%mod; }else { sum[i]=sum[i-1]; } } ll ans=0ll; for(ll i=0ll;i<max(n,m);++i) { if(b[i]=='1') { ans+=sum[i]; ans=(ans+mod)%mod; } } cout<<ans<<endl; return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == ' '); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } } }