• Good Bye 2020 E


    Good Bye 2020 E

    大意

    给定 (N)(N) 个数 (x_1,x_2,...,x_n)

    求: (sum_{i=1}^n sum_{j=1}^n sum_{k=1}^n (x_i \, & \, x_j) cdot (x_j \, | \, x_k))

    思路

    说实话这种题第一时间应该想到位运算...我还是太菜了...

    考虑一步简单变形 (sum_{i=1}^n sum_{j=1}^n sum_{k=1}^n (x_i \, & \, x_j) cdot (x_j \, | \, x_k) = sum_{j=1}^n sum_{i=1}^n (x_i \, & \, x_j) sum_{k=1}^n (x_j \, | \, x_k) = sum_{j=1}^n left[ sum_{i=1}^n (x_i \, & \, x_j) ight] cdot left[ sum_{k=1}^n (x_j \, | \, x_k) ight])

    然后我们想办法 (Theta(log)) 统计方括号中的式子。

    对于固定的 (x_j)(sum_{i=1}^n (x_i \, & \, x_j)) 的值就是 (x_j) 在二进制下的每一位,分别与 (x_1,...,x_n) 做 与 运算的值的累加。

    更简单地说,就是 (x_j) 在二进制下的每一位,与 (x_1,...,x_n) 在二进制下相同的位数做 与 运算的值的累加。

    对于 (x_j)(1) 的位,答案显然就是 (x_1,...,x_n) 在二进制相同的位数为 (1) 的个数乘以此位代表的 (2) 的次幂的值的累加 。

    对于 (x_j)(0) ,显然为 (0)

    这样对于 (j) ,我们在 (logx_j) 的时间内求出了答案。

    对于 (sum_{k=1}^n (x_j \, | \, x_k)) ,方法类似。

    总之,复杂度为 (Theta(Nlog(max(x_i))))

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    #define ll long long
    #define ull unsigned long long
    #define cint const int&
    #define Pi acos(-1)
    
    const int mod = 1e9+7;
    const int inf_int = 0x7fffffff;
    const ll inf_ll = 0x7fffffffffffffff;
    const double ept = 1e-9;
    
    int t, n, mx;
    ll num[62];
    ll a[500500];
    
    void deal(ll x) {
        int cnt=0;
        while(x) {
            if(x&1) ++num[cnt];
            x >>= 1;
            ++cnt;
        }
        mx = max(mx, cnt);
    }
    
    inline ll sol_1(ll x) {
        int cnt=0;
        ll tmp = 0;
        while(x && cnt <= mx) {
            if(x&1) {
                tmp = (tmp + ((1ll<<cnt)%mod*num[cnt]) % mod)%mod;
            }
            x >>= 1;
            ++cnt;
        }
        return tmp;
    }
    
    inline sol_2(ll x) {
        int cnt=0;
        ll tmp = 0;
        while(cnt <= mx) {
            if(x&1) {
                tmp = (tmp + ((1ll<<cnt)%mod*n)%mod)%mod;
            } else tmp = (tmp + ((1ll<<cnt)%mod*num[cnt]) % mod)%mod;
            x >>= 1;
            ++cnt;
        }
        return tmp;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> t;
        ll t1, t2, ans;
        while(t--) {
            memset(num, 0, sizeof num);
            ans = mx = 0;
            cin >> n;
            for(int i=1; i<=n; i++) cin >> a[i], deal(a[i]);
            for(int i=1; i<=n; i++) {
                t1 = sol_1(a[i]);
                t2 = sol_2(a[i]);
                ans = (ans + (t1*t2)%mod) % mod;
            }
            cout << ans << endl;
        }
        return 0;
    }
    

    61min,-0

  • 相关阅读:
    通过HTTP发包工具了解HTTP协议
    Oracle之数据库安全
    SQL注入深入剖析
    apache中如何调用CGI脚本
    fastcgi php-cgi与php-fpm区别和之间的关系
    使用PHPExcel实现Excel文件的导入和导出(模板导出)
    学会数据库读写分离、分表分库
    框架Thinkphp5 简单的实现行为 钩子 Hook
    php文件下载
    PHP为JSON数据的API返回空数组或者空对象
  • 原文地址:https://www.cnblogs.com/ullio/p/14216025.html
Copyright © 2020-2023  润新知