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 ...
随机推荐
- MYSQL 在当前时间加上或减去一个时间段
update user set time1=now(),time2=date_add(NOW(), interval 1 MONTH) where id=1; date_add() 增加date_su ...
- iOS6下实现滑动返回
[转载请注明出处] 之前在看iOS7滑动返回时,发现了一个iOS6 SDK下的第三方实现,今天偶然间发现了作者在其博客上对该实现的一些心得,读来深觉之前的思考太过肤浅,许多实际的问题没有考虑到.帖子链 ...
- windows 下 react-native(v0.56) Android 环境搭建踩坑记录
debugservicereact-native 安装官网 https://reactnative.cn/docs/getting-started.html 根据官网步骤一步步执行下去.还能碰到一些问 ...
- Python练习-一个简单的生成器
今天我们学习了生成器,怎么理解生成器呢,其实就是使用函数的方式自己建立一个迭代器 # 编辑者:闫龙 #做一个简单的生成器 def EasyGene(*args): #建立一个生成器方法并传递多个参数 ...
- Css3帧动画深入探寻,讲点项目中实际会碰到的问题
先加个副标题XD --如何解决background-size为100%下处理@keyframes 正是在项目中遇到副标题,才引起我更深入的探寻 先略带一下基本的css3动画 css3的动画实现是通过属 ...
- 字符串hash&&对字符串hash的理解
对字符串hash的一些总结: 1,首先,我们在转化的时候,取底的时候一般是取131这些数,因为要避免不同的字符串对应相同的hash值这种情况的出现.如果卡精度的时候,我们可以采取双模数的方式尽量减少 ...
- 信息安全学习笔记--XSS
一.XSS简介 XSS (Cross Site Scripting)是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中.比如这些代码包括HTML代 ...
- Java编程思想 4th 第3章 操作符
有了数据,还需要进行数据间的运算,因此Java中也有数据间运算的各种符号,书本称之为操作符,正确的翻译应该是运算符. Java中的运算符同C++相同,运算符同运算符对象构成表达式,表达式是运算对象及运 ...
- UNIX环境高级编程 第14章 高级I/O
这一章涉及很多概念和函数,包括:非阻塞I/O.记录锁.I/O复用.异步I/O.readv和writev函数以及内存映射. 非阻塞I/O 在Unix中,可以将系统调用分为两种,一种是“低速”系统调用,另 ...
- 【多视图几何】TUM 课程 第4章 同名点匹配
课程的 YouTube 地址为:https://www.youtube.com/playlist?list=PLTBdjV_4f-EJn6udZ34tht9EVIW7lbeo4 .视频评论区可以找到课 ...