zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    Appium教程
    ES6对象类型判断
    MyBatisPlus的时间段和模糊查询
    一个div中多个元素垂直居中的一种解决办法
    @JsonFormat与@DateTimeFormat注解的使用
    java日期类型对象通过mybatis向数据库中的存取
    Vue.js单向绑定和双向绑定实例分析
    Maven的使用
    如何将本地的项目提交到码云的远程仓库
    Linux CentOS7 的安装
  • 原文地址:https://www.cnblogs.com/mltang/p/9726827.html
Copyright © 2011-2022 走看看