zoukankan      html  css  js  c++  java
  • Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences(DP)

    题目链接:http://codeforces.com/contest/1058/problem/E

    题意:给出 n 个数,对于一个选定的区间,区间内的数可以通过重新排列二进制数的位置得到一个新的数,问有多少个区间满足,区间内的数异或和为 0 。

    题解:首先对于一个区间来说,区间内二进制为 1 的个数为奇数时显然不可能满足条件,先统计二进制为 1 的个数为偶数的区间总个数。而在一个区间内,如果某个数二进制下有 x 个 1 ,而区间内其他数的二进制 1 加起来小于 x ,则是不满足的,可以暴力去掉这些不合法的区间。因为一个数 <= 1e18,二进制位为 1 最多只有 59 位。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define mst(a,b) memset((a),(b),sizeof(a))
     6 #define mp(a,b) make_pair(a,b)
     7 #define pi acos(-1)
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 const int INF = 0x3f3f3f3f;
    11 const double eps = 1e-6;
    12 const int MAXN = 3e5 + 10;
    13 const int MAXM = 2e6 + 10;
    14 
    15 int a[MAXN];
    16 ll cnt[2][MAXN];
    17 
    18 int main() {
    19 #ifdef local
    20     freopen("data.txt", "r", stdin);
    21 //    freopen("data.txt", "w", stdout);
    22 #endif
    23     int n;
    24     scanf("%d",&n);
    25     cnt[0][0] = 1;
    26     int sum = 0;
    27     for(int i = 1; i <= n; i++) {
    28         ll b;
    29         scanf("%lld",&b);
    30         int num = 0;
    31         while(b) {
    32             if(b & 1) num++;
    33             b >>= 1;
    34         }
    35         a[i] = num;
    36         sum += num;
    37         cnt[0][i] = cnt[0][i - 1], cnt[1][i] = cnt[1][i - 1];
    38         cnt[sum % 2][i]++;
    39     }
    40     ll ans = 0;
    41     for(int i = 1; i <= n; i++) {
    42         if(i == 1 || cnt[0][i - 1] - cnt[0][i - 2]) ans += cnt[0][n] - cnt[0][i - 1];
    43         else ans += cnt[1][n] - cnt[1][i - 1];
    44         int mn = min(n, i + 60), mx = 0;
    45         sum = 0;
    46         for(int j = i; j <= mn; j++) {
    47             sum += a[j];
    48             mx = max(mx, a[j]);
    49             if(sum % 2 == 0 && sum - mx < mx) ans--;
    50         }
    51     }
    52     printf("%lld
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    9. Palindrome Number
    7. Reverse Integer
    6. ZigZag Conversion
    1. Two Sum
    [leetcode]Binary Tree Zigzag Level Order Traversal
    [leetcode]Scramble String
    [leetcode]Convert Sorted Array to Binary Search Tree
    [leetcode]Sum Root to Leaf Numbers
    [leetcode]Longest Consecutive Sequence
    [leetcode]Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/scaulok/p/9696640.html
Copyright © 2011-2022 走看看