• [1525] Cow Xor

  • 时间限制: 2000 ms 内存限制: 65535 K
  • 问题描述
  • 农民约翰在喂奶牛的时候被另一个问题卡住了。他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序。奶牛#1有最高的社会等级,奶牛#N最低。每个奶牛同时被指定了一个不唯一的附加值,这个数在0..2^21 - 1的范围内。

    帮助农民约翰找出应该从哪一头奶牛开始喂,使得从这头奶牛开始的一个连续的子序列上,奶牛的附加值的异或最大。

    如果有多个这样的子序列,选择结尾的奶牛社会等级最高的。如果还不唯一,选择最短的。

  • 输入
  • 第1行:一个单独的整数N。
    第2到N + 1行:N个0..2^21 - 1之间的整数,代表每头奶牛的被赋予的数。第j行描述了社会等级j - 1的奶牛。
  • 输出
  • 第 1 行: 3个空格隔开的整数,分别为:最大的异或值,序列的起始位置、终止位置
  • 样例输入
  • 5
    1
    0
    5
    4
    2
  • 样例输出
  • 6 4 5
  • 提示
  • 最大异或值为6,从第4个开始喂,到第5个结束。
    4 异或 2 = 6
    (100) 异或 (010) = (110)
  • 来源
  • USACO (NOCOW)

题目链接:NBUT 1525

求一段连续异或最大值,假设连续区间为[L,R]则是由pre[L-1]^pre[R]而来,然后枚举每一个pre[i]即可,每一次查找的时间复杂度为O(20)左右,然后题目就变成了求两个pre的最大异或和的情况,跟xorsum就一样了,不过要注意的是对pre[i]求出来的最优异或组合pre[j]后其实得到的是最优xorsum[i+1,j],因此左区间要加一;除此之外根据题意进行特判并且还有要考虑直接取当前值区间端点相等时候特判,调试调试就差不多了。

给几组容易错的数据:

5

5 5 6 6 7

答案为 7 5 5(题目数据不够强,之前代码答案为7 4 5 也可以AC)

5

0 1 1 0 0

答案为 1 2 2

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0); const int N=100010; struct info
{
int val,S;
info *nxt[2];
info()
{
val=0;
S=-1;
nxt[0]=nxt[1]=NULL;
}
}; info *L;
int arr[N];
int pre[N];
void update(int n,int p)
{
bitset<21> bit(n);
info *cur=L;
int indx,i;
for (i=20; i>=0; --i)
{
indx=bit[i];
if(cur->nxt[indx])
cur=cur->nxt[indx];
else
{
info *one=new info();
cur->nxt[indx]=one;
cur=one;
}
}
cur->val=n;
if(cur->S==-1||p<cur->S)//前缀结尾位置尽量靠前
cur->S=p;
}
pii query(int n)
{
info *cur=L;
bitset<21> bit(n);
int indx,i;
for (i=20; i>=0; --i)
{
indx=bit[i];
if(cur->nxt[indx^1])
cur=cur->nxt[indx^1];
else
cur=cur->nxt[indx];
}
return pii(cur->val,cur->S);
}
int read()
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
int main(void)
{
int n,i,l,r,ans,val;
while (~scanf("%d",&n))
{
getchar();
arr[0]=0;
L=new info();
for (i=1; i<=n; ++i)
{
arr[i]=read();
pre[i]=pre[i-1]^arr[i];
update(pre[i],i);
}
int tl,tr,dx,res;
ans=0;
for (i=0; i<=n; ++i)
{
pii temp=query(pre[i]); res=max(temp.first^pre[i],arr[i]);
tl=min(temp.second+1,i);
tr=max(temp.second,i);
dx=tr-tl;
if(arr[i]==res)
{
if(i<tr)
{
tl=tr=i;
dx=0;
}
else if(i==tr&&0<dx)
{
dx=0;
tl=tr=i;
}
}
if(res>ans)
{
ans=res;
l=tl;
r=tr;
}
else if(res==ans)
{
if(r>tr)
{
r=tr;
l=tl;
}
else if(r==tr&&dx<r-l)
l=tl;
}
}
printf("%d %d %d\n",ans,l,r);
}
return 0;
}

NBUT 1525 Cow Xor(01字典树+前缀思想)的更多相关文章

  1. POJ - 3764 01字典树+前缀异或和

    异或关于前缀的特性:[u,v]=[1,u]^[1,v] 注意是路径,假设1为根,prexor[1]不保留数值 /*H E A D*/ int to[maxn<<1],nxt[maxn< ...

  2. HDU 4825 Xor Sum (模板题)【01字典树】

    <题目链接> 题目大意: 给定n个数,进行m次查找,每次查找输出n个数中与给定数异或结果最大的数. 解题分析: 01字典树模板题,01字典树在求解异或问题上十分高效.利用给定数据的二进制数 ...

  3. 51nod 1295 XOR key 可持久化01字典树

    题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...

  4. [BZOJ4260] Codechef REBXOR (01字典树,异或前缀和)

    Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,-,AN. Output 输出一行包含给定表达式可能的最大值. Sample ...

  5. P4551 最长异或路径 (01字典树,异或前缀和)

    题目描述 给定一棵 n 个点的带权树,结点下标从 1 开始到 N .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式: 第一行一 ...

  6. 2014百度之星资格赛—— Xor Sum(01字典树)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  7. Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)

    Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...

  8. Codeforces 948 数论推导 融雪前缀和二分check 01字典树带删除

    A. 全部空的放狗 B. 先O(NLOGNLOGN)处理出一个合数质因数中最大的质数是多少 因为p1 x1 x2的关系是 x2是p在x1之上的最小倍数 所以x1的范围是[x2-p+1,x2-1]要使最 ...

  9. Xor Sum---hdu4825(01字典树模板)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4825 题意:有n个数m个查找,每个查找有一个数x, 从序列中找到一个数y,使得x异或y最大 ...

随机推荐

  1. HDU1850 Being a Good Boy in Spring Festival(博弈)

    Being a Good Boy in Spring Festival Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I ...

  2. [Linux] 孤儿进程与僵尸进程[总结]

    转载: http://www.cnblogs.com/Anker/p/3271773.html 1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...

  3. VelocityTracker简介

    android.view.VelocityTracker主要用跟踪触摸屏事件(flinging事件和其他gestures手势事件)的速率.用addMovement(MotionEvent)函数将Mot ...

  4. How to Optimize Battery Health?

    1. click on the battery icon from taskbar next to the date and time. 2. click "More power optio ...

  5. Java 全半角转换

    * 全角转半角的 转换函数* @return String*/public static final String full2HalfChange(String QJstr){StringBuffer ...

  6. Fresco 源码分析(一) DraweeView-DraweeHierarchy-DraweeController(MVC) DraweeHierachy+DraweeController的分析

    4.1.5.2 模型层DraweeHierachy继承体系以及各个类的作用 DraweeHierachy (I) --| SettableDraweeHierarchy (I) ------| Gen ...

  7. PowerDesigner破解

    1.从百度云盘下载:我的网盘 -- 开发工具空间 -- PowerDesgner12   2.安装powerDesigner   3.将Sybase.PowerDesigner.v12.5-Crack ...

  8. hdu 4005 双联通 2011大连赛区网络赛E *****

    题意: 有一幅图,现在要加一条边,加边之后要你删除一条边,使图不连通,费用为边的费用,要你求的是删除的边的最小值的最大值(每次都可以删除一条边,选最小的删除,这些最小中的最大就为答案) 首先要进行缩点 ...

  9. View、ViewGroup (转)

    Android原理揭秘系列之View.ViewGroup (转) Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGrou ...

  10. Android SDK、ADT认识

    Android SDK: (software development kit)软件开发工具包. 包含一些实用的Android sdk api,供开发者使用,就像开发java程序需要的使用JDK一样. ...