码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #512 E - Vasya and Good Sequences

时间:2018-09-29 22:43:34      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:add   name   sizeof   and   mem   条件   最大   str   奇数   

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

 

这个题首先说了求的是好区间的个数,  好区间满足条件: 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\n",ans);
}

 

Codeforces Round #512 E - Vasya and Good Sequences

标签:add   name   sizeof   and   mem   条件   最大   str   奇数   

原文地址:https://www.cnblogs.com/mltang/p/9726827.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!