• Codeforces Round #512 E


    有时候觉得自己就是个思路搬运机,只会搬运思路

    这个题首先说了求的是好区间的个数,  好区间满足条件: 1、二进制位1的数量和为偶数    2、w[i]表示a[i]的二进制上1的个数 ,sum[i] = w[1] + ... + w[i],对于l-r区间上任意一个位置j,w[j] < sum[r] - sum[l] - w[j]

    设置一个dp[n][2] 数组,dp[i][0]代表     以i为结尾的,区间内二进制1的个数和为偶数的    区间个数

              dp[i][1]代表     以i为结尾的,区间内二进制1的个数和为奇数的    区间个数

    然后再用dp[i][0]  -  所有不满足条件2的区间,把所有满足的区间求和即可

    这个1<=a[i] <= 1e8  1e8比这个long long要小,60二进制位就可以保存,    所以这个  l - r  这个区间    最大的w[j] 其实也就是60不到,最小的w[i] 也是1 ,所以当你这个区间长度大于60,必定满足条件2

    附上我丑陋无比的ac代码

     #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<string>
    using namespace std;
    #define ll long long
    #define se second
    #define fi first
    int n;
    const int maxn = 300010;
    long long arr[maxn];
    int w[maxn];
    int sum[maxn];
    int dp[maxn][2];
    int main()
    {
        memset(w,0,sizeof(w));
        scanf("%d",&n);
        for(int i = 1 ; i <= n; ++i)
        {
            scanf("%lld",arr+i);
            long long k = 1;
            for(int j = 0; j < 62; ++j, k <<= 1)
            {
                if( k & arr[i] )
                    w[i] ++;
            }
            //cout << w[i] << endl;
        }
        dp[1][0] = dp[1][1] = dp[0][0] = dp[0][1] = 0;
        for(int i = 2; i <= n; ++i)
        {
            //cout << w[i] << endl;
            if(w[i] % 2 == 1)
            {
                dp[i][0] = dp[i-1][1]+(w[i-1]%2);
                dp[i][1] = dp[i-1][0]+!(w[i-1]%2);
            }
            else
            {
                dp[i][0] = dp[i-1][0]+!(w[i-1]%2);
                dp[i][1] = dp[i-1][1]+(w[i-1]%2);
            }
        }
        ll ans = 0;
        for(int i = 2; i <= n; ++i)
        {
            ll add = 0;
            ll mx = w[i];
            ll sum = w[i];
            for(int j = i-1; j >= 1 && i-j<=70; --j)
            {
                if(mx < w[j]) mx = w[j];
                sum += w[j];
                if(mx > sum - mx && sum % 2 == 0)
                    add --;
            }
            //cout << dp[i][0] << endl;
            //cout << add << endl;
            add += dp[i][0];
            ans += add;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    原创的java数据访问框架
    在ASP.NET中使用Session常见问题集锦
    Infragistics中WebGrid的MultiColumn Headers设计
    常用asp.net代码
    如何实现函数IF的嵌套超过七层?
    Microsoft® Visual Studio® 2005 Team Suite Service Pack 1
    ASP.NET中常用的文件上传下载方法
    ASP.NET 2.0:使用用户控件和定制的Web部件个人化你的门户网站
    office2007TW
    http://www.ydowns.com/download/53279.rar
  • 原文地址:https://www.cnblogs.com/mltang/p/9726827.html
Copyright © 2020-2023  润新知