zoukankan      html  css  js  c++  java
  • UPC9575 鑫鑫的算术

    题目描述

    AK掉五校联考的题目后,鑫鑫在研究二进制在数论中的应用。

    鑫鑫给了你n个数,每次你可以从这其中选择两个数a和b,将它们的值分别赋为a and b和a or b(均为二进制位运算)。这样的操作,你可以执行任意多次。鑫鑫希望最终这些数的平方和尽量的大,你能帮他求出这个最大值吗?

    输入

    第一行一个正整数n,表示数的数量。
    第二行n个非负整数,表示鑫鑫给你的n个数。(2≤n≤100000,0≤ai≤108)

    输出

    一行一个非负整数,表示答案。由于答案太大,你只需要输出答案对998244353(=7×17×223+1,一个质数)取模后的结果。

    样例输入

    5
    1 2 3 4 5
    

    样例输出

    99


    此类可以操作无限次的题目,一般均与具体的操作执行过程无关,在操作足够次后,会达到一种最优的稳定状态。
    在此题中,可以发现,a和b在做题中所给操作前后其二进制各位上1的数目不变,(a、b 和 a&b、a|b 各二进制位上的一的数目相同)。所以题中所给的操作本质上是将一个数某二进制位上的1换到另一个数上。所以我们
    可以直接求出所有二进制位上1的数目,然后直接构造组成最大结果的数。

    #include "bits/stdc++.h"
    
    using namespace std;
    typedef long long ll;
    int bit[50];
    const int mod = 998244353;
    
    int main() {
        //freopen("input.txt", "r", stdin);
        int n;
        scanf("%d", &n);
        ll temp;
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &temp);
            for (int j = 0; j < 31; j++) {
                if (temp & (1 << j)) {
                    bit[j]++;
                }
            }
        }
        ll ans = 0;
        while (n--) {
            temp = 0;
            for (int i = 0; i < 31; i++) {
                if (bit[i] > 0) {
                    temp += (1 << i);
                    bit[i]--;
                }
            }
            ans = (ans + temp * temp) % mod;
        }
        printf("%lld
    ", ans);
        return 0;
    }
     
  • 相关阅读:
    emlog6.0代码审计
    Linux系统
    PHP反序列化链挖掘
    Yii框架反序列化RCE利用链分析
    CVE-2020-1472漏洞复现
    linux 报错 Input/output error
    SKimage
    layui 统计行totalRow 保留两位小数
    linux清空历史命令(history)
    shred 命令详解
  • 原文地址:https://www.cnblogs.com/albert-biu/p/10305696.html
Copyright © 2011-2022 走看看