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. 转:Block原理及引用循环问题

    2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...

  2. Linux系统自动备份的Shell

    公司现在需要对现有的服务器进行定期备份,并将备份文件放置到正在使用的NAS中去: 为了备份的效率,还需要对备份的文件进行筛选,排除一些后缀名的文件: 实现方法如下: 1. 编写备份的shell文件 在 ...

  3. Spring容器事件、自定义事件

    Spring容器内置事件,如容器的启动.停止.关闭.销毁等事件 <bean name="contextStartedHandler" class="com.nuts ...

  4. 线搜索(line search)方法

    在机器学习中, 通常需要求某个函数的最值(比如最大似然中需要求的似然的最大值). 线搜索(line search)是求得一个函数\(f(x)\)的最值的两种常用迭代方法之一(另外一个是trust re ...

  5. js 禁用右键菜单、拖拽、选中、复制

    //禁用拖拽 document.ondragstart = function () { return false; }; /** * 禁用右键菜单 */ document.oncontextmenu ...

  6. Grunt、gulp、webpack、不要听着高大上你就上,试试Codekit?

    下载地址:https://incident57.com/codekit/ 官方网站了解更多 要编译Less.Sass.Stylus, CoffeeScript, Typescript, Jade, H ...

  7. Css3帧动画深入探寻,讲点项目中实际会碰到的问题

    先加个副标题XD --如何解决background-size为100%下处理@keyframes 正是在项目中遇到副标题,才引起我更深入的探寻 先略带一下基本的css3动画 css3的动画实现是通过属 ...

  8. 单调栈(G - Sliding Window POJ - 2823 )

    题目链接:https://cn.vjudge.net/contest/276251#problem/G 题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值 ...

  9. windebug常用命令

    使用~查看所有线程 切换到一号线程:~1s 查看所有线程的托管堆栈  ~* e!clrstack 怎么查看,当前线程下,变量的信息? 对于托管代码而言,最核心的命令就是!do(dump object的 ...

  10. 键盘ASCII码

    回车键 -- CR 键0x0d   -- 16进制13 -- 10 进制'\r' -- 也可以 换行键 -- LF0x0a   -- 16进制10 -- 10 进制'\n' -- 也可以 esc键   ...