• P5390 [Cnoi2019]数学作业


    P5390 [Cnoi2019]数学作业
    求子集异或和的和
    拆成2进制,假设有x个数这一位为1,剩下n-x个数对答案没有贡献,对于这一位而言,对答案的贡献就是,x个数选奇数个数的方案数*2^(n-x).
    由二项式定理,(1-1)^x=sigema(0,x) (-1)^i*(x,i)=0
    选奇数个和选偶数个方案是相同的,总共是2^x,这样就是2^(x-1).
    所以这一位的答案为:2^(x-1) * 2^(n-x)=2^(n-1)
    所以对于所以所有位而言,总的答案就是所有数或起来*2^(n-1)

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define P 998244353
    #define N 3000010
    #define p(a) putchar(a)
    #define For(i,a,b) for(long long i=a;i<=b;++i)
    //by war
    //2019.8.19
    using namespace std;
    long long T,n,a[N],ans;
    void in(long long &x){
        long long y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(long long x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    long long ksm(long long a,long long b){
        long long r=1;
        while(b>0){
            if(b&1)
                r=r*a%P;
            a=a*a%P;
            b>>=1;
        }
        return r;
    }
    signed main(){
        in(T);
        while(T--){
            in(n);
            ans=0;
            For(i,1,n){
                in(a[i]);
                ans|=a[i];
            }
            o(ans*ksm(2,n-1)%P);p('
    ');
        }
        return 0;
    }
  • 相关阅读:
    合并两个有序数组
    删除排序数组中的重复项 II
    对称二叉树
    相同的树
    二叉树的最大深度
    从前序与中序遍历序列构造二叉树
    vue简单案例_动态添加删除用户数据
    对vue的初步学习(一)
    关于java for循环常见练习题
    关于java中循环的学习
  • 原文地址:https://www.cnblogs.com/war1111/p/11376014.html
Copyright © 2020-2023  润新知