XOR 游戏

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5715

Description

众所周知,度度熊喜欢XOR运算(XOR百科)

今天,它发明了一种XOR新游戏,最开始,它有一个长度为N的数组,度度熊可以任意添加分割线,将数组划分为M段,且每段长度小于等于L。

当然这是个和XOR有关的游戏,度度熊希望所有分组内异或和的最小值最大。

比如,长度为4的数组{1,2,3,4},L为3,可以划分为{1|2,3,4} 或 {1,2|3,4} 或 {1,2,3|4},最小的异或值分别为1,3,0,所以选第二种分割方法。

Input

第一行为T,表示输入数据组数。

对于每组数据,第一行包含三个整数N,M,L,第二行包含N个数,表示数组。

1≤T≤300

1≤N≤10000,1≤M≤10,1≤L≤N

1≤Ai≤109

Output

对第i组数据,输出

Case #i:

然后输出一行,仅包含一个整数,表示满足条件分组方法的最小异或值。

Sample Input

2

4 2 3

1 2 3 4

4 3 2

5 4 3 2

Sample Output

Case #1:

3

Case #2:

2

Hint

题意

题解:

两种方法,一种是按位分析,一种是二分答案

二分答案的话,我们令dp[i][j]表示考虑到第i个数,我划分了j次,是否最小值的答案超过了mid

这个就直接dp转移就好了,每次我们在字典树里面找到最大的a[i]^a[k],然后从dp[k][j-1]转移过来就好了

转移的前提是dp[k][j-1]也是合法的

代码

#include<bits/stdc++.h>
using namespace std; const int maxn = 5e5+5;
int a[maxn],n,m,k,cnt[12];
struct node
{
int ch[2],sum;
void init()
{
ch[0]=ch[1]=sum=0;
}
}T[12][maxn];
void add(int p,int x)
{
int cur = 1;
T[p][cur].sum++;
for(int i=30;i>=0;i--)
{
int y = x>>i&1;
if(!T[p][cur].ch[y])T[p][cur].ch[y]=++cnt[p];
cur=T[p][cur].ch[y];
T[p][cur].sum++;
}
}
void del(int p,int x)
{
int cur = 1;
T[p][cur].sum--;
for(int i=30;i>=0;i--)
{
int y = x>>i&1;
if(!T[p][cur].ch[y])T[p][cur].ch[y]=++cnt[p];
cur=T[p][cur].ch[y];
T[p][cur].sum--;
}
}
int query(int p,int x)
{
int cur=1,ans=0;
if(T[p][1].sum==0)return 0;
for(int i=30;i>=0;i--)
{
int y = x>>i & 1;
if(T[p][T[p][cur].ch[y^1]].sum)
ans+=1<<i,cur=T[p][cur].ch[y^1];
else
cur=T[p][cur].ch[y];
}
return ans;
}
int dp[maxn][12];
int check(int mid)
{
for(int i=0;i<=m+1;i++)
for(int j=1;j<=cnt[i];j++)
T[i][j].init();
for(int i=0;i<=m+1;i++)cnt[i]=1;
for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)
dp[i][j]=0;
dp[0][0]=1,add(0,0);
for(int i=1;i<=n;i++)
{
for(int j=0;j<m;j++)
{
if(i>k&&dp[i-k-1][j])
del(j,a[i-k-1]);
int tmp=query(j,a[i]);
if(tmp>=mid)
{
add(j+1,a[i]);
dp[i][j+1]=1;
}
}
}
return dp[n][m];
}
void solve(int cas)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)a[i]^=a[i-1];
int l=0,r=1e9+7,ans=l;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))l=mid+1,ans=mid;
else r=mid-1;
}
printf("Case #%d:\n%d\n",cas,ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
solve(i);
return 0;
}

HDU 5715 XOR 游戏 二分+字典树的更多相关文章

  1. HDU5715 XOR 游戏 二分+字典树+dp

    当时Astar复赛的时候只做出1题,赛后补题(很长时间后才补,懒真是要命),发现这是第二简单的 分析: 这个题,可以每次二分区间的最小异或和 进行check的时候用dp进行判断,dp[i][j]代表前 ...

  2. HDU 4825 Xor Sum(字典树)

    嗯... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 这道题更明确的说是一道01字典树,如果ch[u][id^1]有值,那么就向下继续查找/ ...

  3. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  4. HDU 4757 Tree 可持久化字典树

    Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...

  5. HDU4825 Xor Sum(字典树解决最大异或问题)

    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整 ...

  6. HDU-4825 Xor Sum(字典树求异或最大值)

    题目链接:点此 我的github地址:点此 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整 ...

  7. HDU 4287 Intelligent IME(字典树数组版)

    Intelligent IME Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. hdu 4099 Revenge of Fibonacci 字典树+大数

    将斐波那契的前100000个,每个的前40位都插入到字典树里(其他位数删掉),然后直接查询字典树就行. 此题坑点在于 1.字典树的深度不能太大,事实上,超过40在hdu就会MLE…… 2.若大数加法时 ...

  9. HDU--5269 ZYB loves Xor I (字典树)

    题目电波: HDU--5269 ZYB loves Xor I 首先我们先解决 ai xor aj 每个数转化为二进制  我们用字典树统计 每个节点 0 和 1 的出现的个数 #include< ...

随机推荐

  1. clog,cout,cerr 输出机制

    clog:控制输出,使其输出到一个缓冲区,这个缓冲区关联着定义在 <cstdio> 的 stderr. cerr:强制输出刷新,没有缓冲区. cout:控制输出,使其输出到一个缓冲区,这个 ...

  2. Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等

    http://blog.csdn.net/h7870181/article/details/8653865 以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后 ...

  3. python网络编程-Select\Poll\Epoll异步IO

    首先列一下,sellect.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select ...

  4. Service(二):通信

    课程:http://www.jikexueyuan.com/course/715_3.html?ss=1 在activity和service之间通信. 首先使用的是启动服务来通信.注意是如何使用Int ...

  5. opencv之dft及mat类型转换

    跑实验时用到dft这个函数,根据教程,需要先将其扩充到最优尺寸,但我用逆变换后发现得到的mat的维数竟然不一样.因此还是不要扩展尺寸了. 参考:http://www.xpc-yx.com/2014/1 ...

  6. 追MM与设计模式

    1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德基就是生产鸡翅 ...

  7. Python基础 - 正则表达式

    Python自带正则表达式模块,即re模块. 导入正则模块: import re 用dir()函数查看re模块内的属性和方法: dir(re)

  8. java 多线程总结篇3之——生命周期和线程同步

    一.生命周期 线程的生命周期全在一张图中,理解此图是基本: 线程状态图 一.新建和就绪状态 当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时它和其他的Java对象一样,仅仅由Jav ...

  9. Vue-Socket.io

    github地址:https://github.com/MetinSeylan/Vue-Socket.io 安装: npm install vue-socket.io -S 注册: import Vu ...

  10. CentOS 6.5通过yum安装和配置MySQL

    0x00 说明 Linux安装MySQL一共有两种方式,一种是下载安装包离线安装,另一种就是通过yum在线安装,这里先介绍在线安装的方式,此方法简单方便,出错最少,但是无法控制安装的MySQL版本,如 ...