zoukankan      html  css  js  c++  java
  • hihocoder1506序列的值

    题目: 戳这里

    题意:有一个长度为n(n <= 100000)的序列a[1.. n],对于任一子序列b[1..m],有f(b[1...m])等于有多少个i (0<=i<m)使得(0^b[1]^b[2]^....^b[i])<(0^b[1]^b[2]^....^b[i]^b[i+1]),然后求a[1....n]所有子序列的值之和。

    思路:这个问题可以转化成:对于a[i]来说,可以从a[1...n]中抽出多少个子序列(子序列中包含a[i]),使得a[i]^S(S是子序列中a[i]前面的部分的异或和)>S,然后累加每个a[i]的贡献就是答案了。

    想要使a[i]^S>S,只能在a[i]二进制最高位是1的那一位,S的对应位是0,否则无法使a[i]^S>S。所以a[i]的前半部分的数量等于a[i]的最高位对应的哪一位异或和是0的子序列个数,这个可以用dp维护,定义dpij 表示第i位所有的异或和是j的子序列个数。然后用a[i]的对应位转移一下就可以了。a[i]的后半部分可以任意取,所以a[i]的贡献=前半部分的方案数*2^(n-i);

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    const ll mod = 998244353;
    const int maxn = 1e5 + 10;
    ll pow1[maxn];
    ll a[maxn], n;
    ll dp[100][2];
    void init()
    {
        pow1[0] = 1;
        for(int i = 1; i < maxn; i++) pow1[i] = pow1[i - 1] * 2%mod;
    }
    
    int main()
    {
        init();
        scanf("%lld",&n);
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; i++)
            scanf("%lld",&a[i]);
        ll ans = 0;
        for(int i = 0 ; i <= 32; i++) dp[i][0] = 1;
        for(int i = 1; i <= n; i++)
        {
            int bit;
            for(bit = 31 ; ((a[i]>> bit)&1)==0; bit--);
            (ans += ((dp[bit][0]* (ll)pow1[n - i])%mod))%=mod;
            for(bit = 0 ; bit <= 32; bit++)
            {
                ll l = dp[bit][0];
                ll r = dp[bit][1];
                ll x = (a[i]>>bit)&1;
                if(x)
                {
                    dp[bit][0] = (l + r)%mod;
                    dp[bit][1] = (l + r)%mod;
                }
                else
                {
                    dp[bit][0] = l * 2%mod;
                    dp[bit][1] = r * 2%mod;
                }
            }
        }
        printf("%lld
    ",ans);
    }
    View Code
  • 相关阅读:
    java 下载图片并传输(java自带 BASE64工具进行图片和字符串转换)
    MySQL的日期格式
    eclipse下查看maven下载的源码中文乱码问题
    Linux----部署
    python----logging
    python----pymysql
    vmware15 激活秘钥
    vmware15 激活秘钥
    Ubuntu18.04安装
    msyql45讲 20--幻读是什么,幻读有什么问题?
  • 原文地址:https://www.cnblogs.com/rtyfcvb/p/7085890.html
Copyright © 2011-2022 走看看