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的更多相关文章

  1. NBUT 1525 Cow Xor(01字典树+前缀思想)

    [1525] Cow Xor 时间限制: 2000 ms 内存限制: 65535 K 问题描述 农民约翰在喂奶牛的时候被另一个问题卡住了.他的所有N(1 <= N <= 100,000)个 ...

  2. [USACO]6.1.3 cow xor(二进制+Trie)

    题意:给你一个序列(n<=100000),求出一个连续的子序列[i,j]使得ai xor ai+1 xor…… xor aj最大,求出这个最大值(其中每个数<=2^21) 分析:题目和求一 ...

  3. USACO 2.3 Cow Pedigrees

    Cow Pedigrees Silviu Ganceanu -- 2003 Farmer John is considering purchasing a new herd of cows. In t ...

  4. USACO 2012 Feb Cow Coupons

    2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...

  5. USACO 2.4 Cow Tours

    Cow Tours Farmer John has a number of pastures on his farm. Cow paths connect some pastures with cer ...

  6. [1525] Cow Xor

    问题描述 农民约翰在喂奶牛的时候被另一个问题卡住了.他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序.奶牛#1有最高的 ...

  7. [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心

    Description Farmer  John  needs  new  cows! There  are  N  cows  for  sale (1 <= N <= 50,000), ...

  8. USACO 2011 November Cow Lineup /// map set 尺取法 oj25279

    题目大意: 输入n 接下来n行描述n头牛的编号num和品种id 得到包含所有id的最短段 输出最短段的编号差 Sample Input 625 726 115 122 320 130 1 Sample ...

  9. 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 ...

随机推荐

  1. 如何在Mongodb中实现数据超时自动删除功能?

    在工作过程中,我们难免会遇到这样的问题,我们想保存一些数据,但是我们对这些数据的要求并不高,有时候往往只是想要某个时间范围内的数据,比如我们如果永远只关心从当前时间往前推半年内的数据特性,那么我们就不 ...

  2. PHP基础知识之————匿名函数(Anonymous functions)

    匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数.最经常用作回调函数(callback)参数的值.当然,也有其它应用的情况. ...

  3. Web Api问题汇总

    在公网上布署Web Api的时候,不能调用,返回404 在web.config中 Adding the following to the web.config file worked for me: ...

  4. Javascript实现返回上一页面并刷新

    今天写了一个小小的提示成功的页面,同时要求返回上一页面,并实现对上一页面的操作进行刷新(例如删除的,添加的),在网上搜寻了一遍,基本上90%的都是说的是用window.history.go(-1), ...

  5. C语言入门教程-(4)常量和变量

    1.常量和变量的概念 程序执行过程中其值不能发生改变的量叫做常量,其值能发生改变的量叫做变量.常量可以直接使用,而变量则必须先定义后才能使用,否则编译器会报错. 2.常量和变量的命名规范 在介绍常量和 ...

  6. Eclipse改变相同代码高亮颜色

    一.点击某一代码时,让相同代码高亮显示(Eclipse默认是这样的) Window ->preferences ->Java ->Editor ->Mark Occurrenc ...

  7. 苹果手机浏览器$(document).on(“click”,function(){})点击无效的问题

    <label class="js_highlight" style="display: inline-block;float: left;width: 50%;&q ...

  8. 【Nginx】 Nginx实现端口转发

    什么是端口转发 当我们在服务器上搭建一个图书以及一个电影的应用,其中图书应用启动了 8001 端口,电影应用启动了 8002 端口.此时如果我们可以通过 localhost:8001 //图书 loc ...

  9. Python使用OpenCV实现简单的人脸检测

    文章目录: OpenCV安装 安装numpy 安装opencv OpenCV使用 OpenCV测试 效果图: 注意: 图片人脸检测 程序要求: 技术实现思路 注意 本文使用的环境是:Windows+P ...

  10. 使用python开发一个能够计算带括号的复杂表达式的计算器(只支持加减乘除)

    使用到了模块re,正则,字典等 # 实现简单的加减乘除括号等运算 # Calculator def calculator(expression): print(expression) import r ...