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
  • 相关阅读:
    AOC的服务还不错
    浅谈Java、MySQL的中文排序问题
    祝cnBlogs的Blogger们新年快乐!
    GT 3.9.4以及今天的工作
    堆排序
    桶排序
    常用排序算法稳定性分析
    VS2010远程调试环境配置详解
    基数排序
    如何修改数据库的服务器名称
  • 原文地址:https://www.cnblogs.com/rtyfcvb/p/7085890.html
Copyright © 2011-2022 走看看