zoukankan      html  css  js  c++  java
  • bzoj4245 [ONTAK2015]OR-XOR (贪心)

    4245: [ONTAK2015]OR-XOR

    Time Limit: 10 Sec Memory Limit: 256 MB
    Submit: 856 Solved: 469
    [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 第一行包含两个正整数n,m(1<=m<=n<=500000),分别表示序列的长度和需要划分的段数。 第一行包含n个整数,其中第i个数为a[i] (0<=a[i]<=10^18)。 ## Output 输出一个整数,即总费用的最小值。

    从最高位贪心,判断每一位时加上高位的限制(某些位是否全为(0))即可;
    因为段内是异或运算,所以两个满足限制的段合并后仍满足限制;
    然后就变成了判断每一位能否分成不少于(m)个满足限制且这一位异或和为(0)的段;
    AC GET☆DAZE

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define N 500039
    #define mod 20070831
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    int n,m,cnt;
    ll num[N],now,ans;
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int a=1;a<=n;a++)
    	{
    		scanf("%lld",&num[a]);
    	}
    	for(int a=60;~a;a--)
    	{
    		cnt=now=0;
    		for(int b=1;b<=n;b++)
    		{
    			now^=num[b];
    			if((now>>(a+1)<<(a+1)|ans)==ans && !(now>>a&1))
    			{
    				cnt++,now=0;
    			}
    		}
    		if(cnt<m || now) ans|=(1ll<<a);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    06-图3 六度空间
    06-图2 Saving James Bond
    06-图1 列出连通集
    05-树9 Huffman Codes
    数据结构学习笔记04树(堆 哈夫曼树 并查集)
    05-树8 File Transfer
    05-树7 堆中的路径
    十天学会单片机Day1点亮数码管(数码管、外部中断、定时器中断)
    设计模式—— 四:接口隔离原则
    设计模式—— 一:单一职责原则
  • 原文地址:https://www.cnblogs.com/Sinogi/p/9114752.html
Copyright © 2011-2022 走看看