NBUT 1525 Cow Xor(01字典树+前缀思想)
[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字典树+前缀思想)的更多相关文章
- POJ - 3764 01字典树+前缀异或和
异或关于前缀的特性:[u,v]=[1,u]^[1,v] 注意是路径,假设1为根,prexor[1]不保留数值 /*H E A D*/ int to[maxn<<1],nxt[maxn< ...
- HDU 4825 Xor Sum (模板题)【01字典树】
<题目链接> 题目大意: 给定n个数,进行m次查找,每次查找输出n个数中与给定数异或结果最大的数. 解题分析: 01字典树模板题,01字典树在求解异或问题上十分高效.利用给定数据的二进制数 ...
- 51nod 1295 XOR key 可持久化01字典树
题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...
- [BZOJ4260] Codechef REBXOR (01字典树,异或前缀和)
Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,-,AN. Output 输出一行包含给定表达式可能的最大值. Sample ...
- P4551 最长异或路径 (01字典树,异或前缀和)
题目描述 给定一棵 n 个点的带权树,结点下标从 1 开始到 N .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式: 第一行一 ...
- 2014百度之星资格赛—— Xor Sum(01字典树)
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Total ...
- 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 ...
- Codeforces 948 数论推导 融雪前缀和二分check 01字典树带删除
A. 全部空的放狗 B. 先O(NLOGNLOGN)处理出一个合数质因数中最大的质数是多少 因为p1 x1 x2的关系是 x2是p在x1之上的最小倍数 所以x1的范围是[x2-p+1,x2-1]要使最 ...
- Xor Sum---hdu4825(01字典树模板)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4825 题意:有n个数m个查找,每个查找有一个数x, 从序列中找到一个数y,使得x异或y最大 ...
随机推荐
- 好玩儿的expect
前言 1> 借鉴里面的应用思想,使用断言提高代码的健壮性及维护性 2> 实现方式——不采用直接嵌入expect的方式,统一进行重写(提取常用断言方法,重新构造API) 官网介绍 https ...
- linux下常见的文件夹含义
1./bin :获得最小的系统可操作性所需要的命令2./boot :内核和加载内核所需的文件3./dev :终端.磁盘.调制解调器等的设备项4./etc :关键的启动文件和配置文件5./home :用 ...
- 5.建造者模式(Builder Pattern)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- NVelocity模板引擎的使用
第一种使用方法直接赋值: VelocityEngine vltEngine = new VelocityEngine(); vltEngine.SetProperty(RuntimeConstants ...
- 如何在postgresql中模拟oracle的dual表,来测试数据库最基本的连接功能?
还好,网上弄到的,,没有dual的数据库,可以试图用select函数不带from数据表的方式来实现返回值. 一段测试代码: try: conn = psycopg2.connect(database= ...
- Xamarin.Android开发实践(十四)
Xamarin.Android之ListView和Adapter 一.前言 如今不管任何应用都能够看到列表的存在,而本章我们将学习如何使用Xamarin去实现它,以及如何使用适配器和自定义适配器(本文 ...
- hdu 4833 离散化+dp ****
先离散化,然后逆着dp,求出每个点能取到的最大利益,然后看有没有钱,有钱就投 想法好复杂 #include <stdio.h> #include <string.h> #inc ...
- 表现层(jsp)、持久层(类似dao)、业务层(逻辑层、service层)、模型(javabean)、控制层(action)
转自:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持久层(Hibernate)之间的松 ...
- AsyncTask下载网络图片
MyTask task = new MyTask(); task.execute(url); class MyTask extends AsyncTask<String, Integer, Bi ...
- char *c和char c[]区别
char *c和char c[]区别 问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者 ...