zoukankan      html  css  js  c++  java
  • Binary Numbers AND Sum CodeForces

    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 (1n,m21051≤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

    Input
    4 4
    1010
    1101
    Output
    12
    Input
    4 5
    1001
    10101
    Output
    11

    Note

    The algorithm for the first example:

    1. add to the answer 10102 & 11012=10002=81010102 & 11012=10002=810 and set b:=110b:=110;
    2. add to the answer 10102 & 1102=102=21010102 & 1102=102=210 and set b:=11b:=11;
    3. add to the answer 10102 & 112=102=21010102 & 112=102=210 and set b:=1b:=1;
    4. 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:

    1. add to the answer 10012 & 101012=12=11010012 & 101012=12=110 and set b:=1010b:=1010;
    2. add to the answer 10012 & 10102=10002=81010012 & 10102=10002=810 and set b:=101b:=101;
    3. add to the answer 10012 & 1012=12=11010012 & 1012=12=110 and set b:=10b:=10;
    4. add to the answer 10012 & 102=02=01010012 & 102=02=010 and set b:=1b:=1;
    5. 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';
            }
        }
    }



    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    Binary Search Tree Iterator
    Oracle迁移:Linux->Windows
    OCP考点实战演练02-日常维护篇
    Oracle数据库全球化
    Oracle管理磁盘空间和资源
    Oracle数据库资源管理
    使用普通用户替代root来管理IEE
    记录一则ORA-12154,ORA-12560解决过程
    Oracle段收缩功能
    Oracle使用SQL传输表空间
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10802670.html
Copyright © 2011-2022 走看看