USACO 6.1 Cow XOR
Cow XOR
Adrian Vladu -- 2005
Farmer John is stuck with another problem while feeding his cows. All of his N (1 ≤ N ≤ 100,000) cows (numbered 1..N) are lined up in front of the barn, sorted by their rank in their social hierarchy. Cow #1 has the highest rank; cow #N has the least rank. Every cow had additionally been assigned a non-unique integer number in the range 0..(221 - 1).
Help FJ choose which cows will be fed first by selecting a sequence of consecutive cows in the line such that the bitwise "xor" between their assigned numbers has the maximum value. If there are several such sequences, choose the sequence for which its last cow has the highest rank. If there still is a tie, choose the shortest sequence.
TIME LIMIT: 0.5 sec
PROGRAM NAME: cowxor
INPUT FORMAT
- Line 1: A single integer N
- Lines 2..N+1: N integers ranging from 0 to 221 - 1, representing the cows' assigned numbers. Line j describes cow of social hierarchy j-1.
SAMPLE INPUT (file cowxor.in)
5
1
0
5
4
2
INPUT DETAILS:
There are 5 cows. Cow #1 had been assigned with 1; cow #2 with 0; cow #3 with 5; cow #4 with 4; cow #5 with 2.
OUTPUT FORMAT
- Line 1: Three space-separated integers, respectively: the maximum requested value, the position where the sequence begins, the position where the sequence ends.
SAMPLE OUTPUT (file cowxor.out)
6 4 5
OUTPUT DETAILS:
4 xor 2 = 6 (001) xor (010) = (011)
————————————————————————题解
首先是死活都没有想出来标解
然后是造福大众的Analysis
Cow XOR
Suppose that we know the k first bits of binary representation of the greatest possible xor. If there exists a sequence such that its xor (which we shall call q) on the first k bits agrees with those -- and the next bit is '1' -- then we know, that k+1'th bit of the greatest xor will be '1', because if not, then q would be greater.
如果我们知道了最棒的异或二进制前k位,存在一个序列使它的k位是这样的,然后下一位是1(如果我们可以办到),因为如果不是答案就不会最大。
The solution first computes values xr[], where xr[q] equals xor of all the cows' values from 1 to q - then, xor of the sequence a..b quals xr[b] xor xr[a-1].
It then runs a loop over all possible exponents e of 2 (starting from 21 downwards), updating arrays pop[] and best[]. It is assumed that after finishing the loop with exponent e (and before entering the loop, with e assumed to be 22), that for every 0 ≤ q ≤ N:
这个解答先定义变量xr[],这是一个异或前缀和【公子是一个力求简洁的翻译】。然后循环二进制拆位从22开始倒序枚举,然后对于每个0 ≤ q ≤ N
- xr[pop[q][0]]'s and xr[q]'s binary representations are the same on positions e, e+1, etc., and pop[q][0] is biggest possible with 0 ≤ pop[q][0] < q. If there's no such pop[q][0] possible, then pop[q][0] = -1.
- xr[pop[q][1]]'s and xr[q]'s binary representations are the same on positions e+1, e+2, etc., different on position e, and pop[q][1] is biggest possible with 0 ≤ pop[q][1] < q. If there's no such pop[q][1] possible, then pop[q][1] = -1.
- if X would be equal biggest possible xor, then xr[best[q]] xor xr[q]'s in equal X's binary representation on positions e, e+1, etc., and best[q] is biggest possible with 0 ≤ best[q] < q. If there's no such best[q] possible, then best[q] = -1.
After performing the loop with e = 0, for each 0 ≤ q ≤ N, best[q] = -1 or xr[best[q]] xor xr[q] is equal X. There exists at least one q with best[q] non-negative, because there exist such a and b, a ≤ b, that xr[a-1] xor xr[b] = X.
The last step will be finding smallest possible q with non-negative best[q], which satisfies, that if there're more possible sequences, we should choose one with last cow having highest rank. The third condition, stating, that if there's still a tie we should choose shortest sequence, is satisfied thanks to the fact, that best[q] is always biggest possible.
这段话,这么个意思【逐句翻译太累,把重点挑出来】
【我们现在枚举到的指数是e】
我们维护个pop[n][2]:
xr[pop[q][0]]和xr[q]二进制[e,22]位都相等,且pop[q][0]是[0,q)中最大的,若找不到赋值-1
xr[pop[q][1]]和xr[q]二进制[e+1,22] 位都相等,且pop[q][0]是[0,q)中最大的,若找不到赋值-1
维护一个best[q]使得在目前情况中[best[q],q]异或的值满足可以达到的[e,22]最大赋值,且best[q]是[0,q)中最大的,若没有best[q]=-1
最后对所有q扫一遍best[q],得出答案
然后这三者怎么求……
我们对于一个best[q]与q,当我们枚举的这一指数e它们异或之后这一位不为1而是0,那么我们就需要考虑更新best[q],因为best[q]存的是xr[q]^xr[best[q]]的[e+1,22]最好结果【事实上也是答案的最好结果】那么我们要改变best[q],设best[q]的新值是y,这个新的xr[y]一定前[e+1,22]位与xr[best[q]]是相同的,这就是pop[q][1]的作用了
当然,如果e这一位无论如何也无法变成1,我们就跳过这一位
pop[q][0]辅助推出pop[q][1]
【别忘了看完这个做法之后下面还有一个很亲民的做法……】
【恭喜您已获得成就,翻译完USACO6.1的全部Analysis】qwq要是会的话还翻译什么Analysis辣
代码来一发【我的天吓死我了感谢博客园的恢复功能……】
/*
ID: ivorysi
LANG: C++
PROG: cowxor
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
#define inf 0x5f5f5f5f
#define ivorysi
#define mo 97797977
#define hash 974711
#define base 47
#define fi first
#define se second
#define pii pair<int,int>
#define esp 1e-8
typedef long long ll;
using namespace std;
int pop[][],best[],a[],xr[],n,e,t;
int tmp[];
void solve() {
scanf("%d",&n);
siji(i,,n) {
scanf("%d",&a[i]);
xr[i]=xr[i-]^a[i];
best[i]=i-;
pop[i][]=i-;
pop[i][]=-;
}
pop[][]=-;pop[][]=-;best[]=-;
e=;
bool one;
while(e--) {
siji(i,,n) {
if(pop[i][]==-) {
pop[i][]=-;
}
else {
if(xr[pop[i][]] >> e != xr[i] >> e) {
tmp[]=pop[pop[i][]][];
/*pop[pop[i][0]]已经计算好了,
xr[pop[pop[i][0]][1]]的[e+1,22]与xr[pop[i][0]]相同
第e位不同,然而现在这种情况正好需要第e位与xr[pop[i][0]]不同
*/
tmp[]=pop[i][];
/*
正好满足前[e+1,22]位相同,第e位不同
*/
}
else {
tmp[]=pop[i][];
/*
正好满足前[e,22]位相同
*/
tmp[]=pop[pop[i][]][];
/*pop[pop[i][0]]已经计算好了,
xr[pop[pop[i][0]][1]]的[e+1,22]与xr[pop[i][0]]相同
第e位不同,然而现在这种情况正好需要第e位与xr[pop[i][0]]不同
*/
}
pop[i][]=tmp[];
pop[i][]=tmp[];
}
}
one=false;
siji(i,,n) {
if(best[i]>=) {
if((xr[best[i]]>>e)% != (xr[i]>>e)% || pop[best[i]][]>=) {
/*
如果e位不相同或者还可以找到更新的说明e位可以为1
*/
one=true;break;
}
}
}
if(one) {
siji(i,,n) {
if(best[i]>=) {
if((xr[best[i]]>>e)% == (xr[i]>>e)%) {
best[i]=pop[best[i]][];
}
}
} }
}
for(t=;best[t]<;++t);
printf("%d %d %d\n",xr[t]^xr[best[t]],best[t]+,t);
}
int main(int argc, char const *argv[])
{
#ifdef ivorysi
freopen("cowxor.in","r",stdin);
freopen("cowxor.out","w",stdout);
#else
freopen("f1.in","r",stdin);
#endif
solve();
return ;
}
第二个做法是我们建一棵01的trie树,插入每一个前缀和,从第21位到第1位
那么我们就可以每次贪心地去查前缀,如果这一位是0我们就尝试往1查,如果这一位是1我们就尝试往0查
由于USACO的空间很小,所以动态建一棵树……
/*
ID: ivorysi
LANG: C++
PROG: cowxor
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
#define inf 0x5f5f5f5f
#define ivorysi
#define mo 97797977
#define hash 974711
#define base 47
#define fi first
#define se second
#define pii pair<int,int>
#define esp 1e-8
typedef long long ll;
using namespace std;
struct node {
node *son[];
int end;
node() {
memset(son,,sizeof(son));
end=;
}
}*root;
int n,a[];
int sum[];
int s,t,ans,x;
void ins(int val,int id) {
node *p=root;
gongzi(i,,) {
x=(val>>i)&;
if(p->son[x]==)
p->son[x]=new node;
p=p->son[x];
}
p->end=max(p->end,id);
}
int calc(int val) {
node *p=root;
gongzi(i,,) {
x=((val>>i)&)^;
if(p->son[x]!=) {
p=p->son[x];
}
else {
p=p->son[x^];
}
}
return p->end;
}
void solve() {
scanf("%d",&n);
siji(i,,n) scanf("%d",&a[i]);
sum[]=;
root=new node;
ins(sum[],);
ans=-;
int pos;
siji(i,,n) {
sum[i]=sum[i-]^a[i];
pos=calc(sum[i]); if((sum[i]^sum[pos])> ans) {
ans=sum[i]^sum[pos];
s=pos+;t=i;
}
ins(sum[i],i);
}
printf("%d %d %d\n",ans,s,t);
}
int main(int argc, char const *argv[])
{
#ifdef ivorysi
freopen("cowxor.in","r",stdin);
freopen("cowxor.out","w",stdout);
#else
freopen("f1.in","r",stdin);
#endif
solve();
return ;
}
USACO 6.1 Cow XOR的更多相关文章
- NBUT 1525 Cow Xor(01字典树+前缀思想)
[1525] Cow Xor 时间限制: 2000 ms 内存限制: 65535 K 问题描述 农民约翰在喂奶牛的时候被另一个问题卡住了.他的所有N(1 <= N <= 100,000)个 ...
- [USACO]6.1.3 cow xor(二进制+Trie)
题意:给你一个序列(n<=100000),求出一个连续的子序列[i,j]使得ai xor ai+1 xor…… xor aj最大,求出这个最大值(其中每个数<=2^21) 分析:题目和求一 ...
- USACO 2.3 Cow Pedigrees
Cow Pedigrees Silviu Ganceanu -- 2003 Farmer John is considering purchasing a new herd of cows. In t ...
- USACO 2012 Feb Cow Coupons
2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...
- USACO 2.4 Cow Tours
Cow Tours Farmer John has a number of pastures on his farm. Cow paths connect some pastures with cer ...
- [1525] Cow Xor
问题描述 农民约翰在喂奶牛的时候被另一个问题卡住了.他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序.奶牛#1有最高的 ...
- [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心
Description Farmer John needs new cows! There are N cows for sale (1 <= N <= 50,000), ...
- USACO 2011 November Cow Lineup /// map set 尺取法 oj25279
题目大意: 输入n 接下来n行描述n头牛的编号num和品种id 得到包含所有id的最短段 输出最短段的编号差 Sample Input 625 726 115 122 320 130 1 Sample ...
- USACO 2009 Open Cow Line /// 队列 oj26220
题目大意: 输入n,n次操作 操作A:在L(左边)或R(右边)插入一个递增的数 操作D:在L(左边)或R(右边)删除m个数 Sample Input 10A LA LA RA LD R 2A RA R ...
随机推荐
- sql server 日志文件占用过多空间
问题描述: 在sql server的log文件夹中存在大量的mdmp.log文件,整体占用了几十个G C:\Program Files (x86)\Microsoft SQL Server\MSSQL ...
- oracle进阶之分析函数
本博客是自己在学习和工作途中的积累与总结,纯属经验之谈,仅供自己参考,也欢迎大家转载,转载时请注明出处. http://www.cnblogs.com/king-xg/p/6797119.html 分 ...
- LeetCode-330.Patching Array
/** * nums的所有元素,假设最大能连续形成[1,sum] 当增加一个element的时候 * 会变成 [1,sum] [element+1,sum+element]两个区间,这两个区间有以下可 ...
- 查看和修改linux系统时间
一.查看和修改Linux的时区1. 查看当前时区 命令 : "date -R" 2. 修改设置Linux服务器时区方法 A 命令 : "tzselect" 方法 ...
- sql 存储时空格转成问号问题
最近做系统,从邮件中导出邮件,上传到系统中,遇到一个奇葩的问题,如下: 通过本地文件看,文件名中是一个空格,上传至数据库后,展示就变成了问号,究其原因,发现是一个特殊字符导致: 最近认真去查了一下这个 ...
- 监控Elasticsearch的插件【check_es_system】
监控Elasticsearch的插件推荐 强大的shell脚本 #!/bin/bash ####################################################### ...
- Java并发编程原理与实战三十五:并发容器ConcurrentLinkedQueue原理与使用
一.简介 一个基于链接节点的无界线程安全队列.此队列按照 FIFO(先进先出)原则对元素进行排序.队列的头部 是队列中时间最长的元素.队列的尾部 是队列中时间最短的元素.新的元素插入到队列的尾部,队列 ...
- 一些达成共识的JavaScript编码约定[转]
如果你的代码易于阅读,那么代码中bug也将会很少,因为一些bug可以很容被调试,并且,其他开发者参与你项目时的门槛也会比较低.因此,如果项目中有多人参与,采取一个有共识的编码风格约定非常有必要.与其他 ...
- mysql sql优化实例1(force index使用)
今天和运维同学一块查找mysql慢查询日志,发现了如下一条sql: SELECT sum(`android` + ios) total,pictureid,title,add_time FROM `j ...
- Windows上安装QT4后更改MinGW的路径
在windows上安装使用MinGW的QT4时,并不会一起安装MinGW. 在安装过程中,会让你指定已经安装的MinGW的路径. 当你使用QT4时,将使用你指定的MinGW的路径下的g++来编译构建程 ...