BZOJ 4245 ONTAK2015 OR-XOR

题目大意:给定一个长度为n的序列,要求分成m段,使得每段异或和的或值最小

求出前缀异或和后从大到小按位确定,如果某一位上有至少m个数是0且第n个数是0,那么这一位就可以是0,同时将所有是1的数字标记为不可选

时间复杂度O(nlogai)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 500500
using namespace std;
int n,m;
long long a[M],ans;
bool v[M];
int main()
{
    int i;
    long long j;
    cin>>n>>m;
    for(i=1;i<=n;i++)
        scanf("%lld",&a[i]),a[i]^=a[i-1];
    for(j=1ll<<62;j;j>>=1)
    {
        int cnt=0;
        for(i=1;i<=n;i++)
            if( !v[i] && ~a[i]&j )
                ++cnt;
        if( cnt>=m && ~a[n]&j )
        {
            for(i=1;i<=n;i++)
                if(a[i]&j)
                    v[i]=true;
        }
        else
            ans|=j;
    }
    cout<<ans<<endl;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 04:49:56

BZOJ 4245 ONTAK2015 OR-XOR的相关文章

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 第一行包含

4245: [ONTAK2015]OR-XOR

4245: [ONTAK2015]OR-XOR https://www.lydsy.com/JudgeOnline/problem.php?id=4245 1 /* 2 要求分成m份,总价值为a1|a2|a3...,总价值最小,ai为第i份的异或和. 3 4 首先预处理异或和. 5 根据贪心的思想,高位最好是0. 6 于是从高位往低位枚举,看一下每一位是否可以为0. 7 如果当前这一位可以为0,每一份的(异或和)(或)起来都是0,所以每一份异或和的这一位不能有1 8 那么一个点可以成为分割点当且

【BZOJ 2115】 [Wc2011] Xor

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 962  Solved: 441 [Submit][Status] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进

【BZOJ】2337: [HNOI2011]XOR和路径

[算法]期望+高斯消元 [题解]因为异或不能和期望同时运算,所以必须转为加乘 考虑拆位,那么对于边权为1取反,边权为0不变. E(x)表示从x出发到n的路径xor期望. 对于点x,有E(x)=Σ(1-E(y))(边权1)||E(y)(边权0)/t[x]  t[x]为x的度. 那么有n个方程,整体乘上t[x]确保精度,右项E(x)移到左边--方程可以各种变形. 每次计算完后*(1<<k)就是贡献. 逆推的原因在于n不能重复经过,而1能重复经过,所以如果计算"来源"不能计算n,

【BZOJ】2115: [Wc2011] Xor

http://www.lydsy.com/JudgeOnline/problem.php?id=2115 题意:给出一个n个点m条边的无向连通边加权图,求1-n的某条路径使得异或值最大(可以重复点可以重复边)(n<=50000, m<=100000) #include <bits/stdc++.h> using namespace std; const int N=50005, M=100015; typedef long long ll; struct E { int next,

BZOJ 4245 OR-XOR

按位贪心. 前缀异或和没话说.一位为0当且仅当这一位有m个0,且第n个数这一位为0. 如果这一位可以为0,那么所有这一位为1的数以后都不能选. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 500050 using namespace std; long long n,m,a[maxn],ans=0,table[70]; bool

【BZOJ 4269】再见Xor

zky学长提供的线性基求法: for(int i=1;i<=n;i++) for(int j=64;j>=1;j--) { if(a[i]>>(j-1)&1) { if(!lb[j]){lb[j]=a[i];break;} else a[i]^=lb[j]; } } Gauss消元求线性基的方法: #include<cstdio> #include<cstring> #include<algorithm> #define read(x)

●BZOJ 4278 [ONTAK2015]Tasowanie

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4278 题解: 把两个串连接起来,用一个大数连接(必须要用大数).倍增算法求出后缀排名.然后两个指针指向A,B串,每次比较两个后缀的大小,优先取出小的那个后缀的首字母,然后对应指针向后移动一位. 代码: #include<cstdio> #include<cstring> #include<iostream> #define MAXN 450000 #define

BZOJ 4276: [ONTAK2015]Bajtman i Okr?g?y Robin

最大权值匹配,贪心匈牙利即可. 检查一些人是否能被全部抓住可以采用左端点排序,右端点优先队列处理. By:大奕哥 #include<bits/stdc++.h> using namespace std; const int N=5005; struct node{ int l,r,c; bool operator <(const node &b)const{ return c>b.c; } }p[N]; int match[N],ans,n; bool v[N]; bool