【BZOJ4245】[ONTAK2015]OR-XOR 贪心

【BZOJ4245】[ONTAK2015]OR-XOR

Description

给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的异或和,则总费用为c[1] or c[2] or ... or c[m]。请求出总费用的最小值。

Input

第一行包含两个正整数n,m(1<=m<=n<=500000),分别表示序列的长度和需要划分的段数。

第一行包含n个整数,其中第i个数为a[i](0<=a[i]<=10^18)。

Output

输出一个整数,即总费用的最小值。

Sample Input

3 2 1 5 7

Sample Output

3

HINT

第一段为[1],第二段为[5 7],总费用为(1) or (5 xor 7) = 1 or 2 = 3。

题解:首先我们肯定要贪心来搞,我们肯定是切的次数越少越好,如果我们想让第i位为0,那么需要切出来的每一段的第i位xor起来都是0

从大到小枚举第i位,如果第i位为1的数的个数为奇数,那么我们无论怎么切答案的第i位肯定都是1,所以不管;如果第i位为1的数的个数为偶数,那么我们将他们两两配对,每对的中间肯定是不能被切过的,剩余位置切不切无所谓。所以我们统计出不能切的数量sum,如果sum+m<=n-1那么这些位置我们就都不切,否则答案的第i位只能是1,切不切我们不管。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=500010;
typedef long long ll;
int n,m,sum,tot;
ll ans;
ll v[maxn];
int s[maxn];
int main()
{
    scanf("%d%d",&n,&m);
    int i,flag=0;
    ll j;
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&v[i]);
    }
    for(j=1ll<<62;j;j>>=1)
    {
        for(sum=0,i=1;i<=n;i++)  if(v[i]&j)  sum++;
        if(sum&1)   ans^=j;
        else
        {
            for(flag=sum=0,i=1;i<n;i++)
            {
                if(v[i]&j)  flag^=1;
                s[i]+=flag,sum+=(s[i]==1)&flag;
            }
            if(sum+tot+m>n)
            {
                ans^=j;
                for(flag=sum=0,i=1;i<n;i++)
                {
                    if(v[i]&j)  flag^=1;
                    s[i]-=flag;
                }
            }
            else    tot+=sum;
        }
    }
    printf("%lld",ans);
    return 0;
}
时间: 2024-09-26 18:39:53

【BZOJ4245】[ONTAK2015]OR-XOR 贪心的相关文章

CF169D2 D – Little Girl and Maximum XOR 贪心

解题思路: 经过打表可得规律答案要么是0 要么是2的N次 要得到最大的XOR值,其值一定是2的N次 即在 l 和 r 的二进制中,从左到右遍历过去,如果碰到 l 为 1 r 为 0 则可说明在『l , r]中存在 1000000000 和 0111111111 可得到最大XOR值为2的N次 PS:不会存在首先出现 l 为 0 r 为 1 的情况,因为 l < r #include<stdio.h> #include<math.h> int main(){ long long

hdu-5661 Claris and XOR(贪心)

题目链接: Claris and XOR Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description Claris loves bitwise operations very much, especially XOR, because it has many beautiful features. He gets four positive int

BZOJ4245 [ONTAK2015]OR-XOR

Description 给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的异或和,则总费用为c[1] or c[2] or ... or c[m].请求出总费用的最小值. Input 第一行包含两个正整数n,m(1<=m<=n<=500000),分别表示序列的长度和需要划分的段数. 第一行包含n个整数,其中第i个数为a[i](0<=a[i]<=10^18). Output 输出一个整数,即总费用的最

D. Little Girl and Maximum XOR(贪心)

D. Little Girl and Maximum XOR A little girl loves problems on bitwise operations very much. Here's one of them. You are given two integers l and r. Let's consider the values of for all pairs of integers a and b (l?≤?a?≤?b?≤?r). Your task is to find

CodeForces 276D – Little Girl and Maximum XOR 贪心

整整10个月后第二次搞这个问题才搞懂........第一次还是太随意了. 解题思路: 经过打表可得规律答案要么是0 要么是2的N次 - 1 要得到最大的XOR值,其值一定是2的N次 - 1 即在 l 和 r 的二进制中,从左到右遍历过去,如果碰到 (2 ^ i) & l 为 1 , (2 ^ i) & r 为 0 即在 l 和 r 之间一定存在 形如 10+ 和01+这样的数. 则可说明在[l , r]中存在 1000000000 和 0111111111 可得到最大XOR值为2的N次 -

待 题表

题表 达哥终极杂题表Bzoj2839 hdu6021 Codeforces 804DBzoj2248 hdu5575 Codeforces 786CBzoj2013 bzoj2676 Codeforces 803CBzoj2386 bzoj3782 Codeforces 813DBzoj2699 cogs1667 Codeforces 814DBzoj4798 bzoj2064 Codeforces 814EBzoj4639 bzoj3505 Codeforces 815ABzoj4417 bz

BZOJ 4245: [ONTAK2015]OR-XOR 贪心

4245: [ONTAK2015]OR-XOR Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 567  Solved: 312[Submit][Status][Discuss] Description 给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的异或和,则总费用为c[1] or c[2] or ... or c[m].请求出总费用的最小值. Input 第一行包含

【BZOJ-4245】OR-XOR 按位贪心

4245: [ONTAK2015]OR-XOR Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 486  Solved: 266[Submit][Status][Discuss] Description 给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的异或和,则总费用为c[1] or c[2] or ... or c[m].请求出总费用的最小值. Input 第一行包含

hdu 4825 Xor Sum(trie+贪心)

hdu 4825 Xor Sum(trie+贪心) 刚刚补了前天的CF的D题再做这题感觉轻松了许多.简直一个模子啊...跑树上异或x最大值.贪心地让某位的值与x对应位的值不同即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #define CLR(a,b) memset((a)