题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5968

异或密码

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1214    Accepted Submission(s): 404

Problem Description
晨晨在纸上写了一个长度为N的非负整数序列{ai}。对于这个序列的一个连续子序列{al,al+1,…,ar}晨晨可以求出其中所有数异或的结果 alxoral+1xor...xorar其
中xor表示位异或运算,对应C、C++、 Java等语言中的^运算。
小璐提出了M个询问,每个询问用一个整数 xi描述。
对于每个询问,晨晨需要找到序列{ai}的所有连续子序列,求出每个子序列异或的结果,找到所有的结果中与 xi之差的绝对值最小的一个,并告诉小璐相应子序列的长度。
若有多个满足条件的连续子序列,则告诉小璐这些子序列中最长的长度。
 
Input
包含多组测试数据,第一行一个正整数T,表示数据组数。
每组数据共两行。
第一行包含N+1个非负整数。其中第一个数为N,表示序列的长度;接下来N 个数,依次描述序列{ ai}中的每个数。
第二行包含M+1个整数。其中第一个数为M,表示询问的个数;接下来M个数 xi,每个数对应题目描述中的一个询问。
保证 1 <= N <= 100,1 <= M <= 100,ai <=
1024,|xi|
<= 1024,数据组数 <= 100。
 
Output
对于每组数据输出M + 1行。前M行对应晨晨M个询问的回答,第M + 1行为空行
 
Sample Input
2
2 1 1
2 0 2
3 1 2 4
3 10 5 1
 
Sample Output
2
1

3
2
1

题解:

1.先预处理出连续子序列的异或值和长度。

2.由于异或值最大只能为2048,所以可以用优先队列保存每个异或值下的长度,用一个数组s[]保存有哪些长度,然后再对s[]数组去重(sort()+unique())。当然不推荐这种做法,因为每个异或值下,只有最大长度是有用的,所以再保存其他值就浪费了空间。推荐的做法是:将每个连续子序列的异或值和长度放到一个结构体里面,然后再对结构体进行排序,最后手动去重。

3.对于每次操作,使用二分试图去找到第一个异或值大于等于x的结构体,然后就是一些有关二分以及其他的细节处理,不细讲。

数组 + 优先队列(不推荐):

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
//#define LOCAL
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[];
int n, m, cnt;
priority_queue<int>q[maxn]; int s[*]; int sch(int x)
{
int l = , r = cnt;
while(l<r)
{
int mid = (l+r)>>;
if(s[mid]>=x)
r = mid;
else
l = mid + ;
}
return r;
} void init()
{
cnt = ;
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%d",&a[i]), a[i] = a[i]^a[i-]; for(int i = ; i<maxn; i++)
while(!q[i].empty()) q[i].pop(); for(int i = ; i<=n; i++)
for(int j = i; j<=n; j++)
{
s[++cnt] = a[j]^a[i-];
q[a[j]^a[i-]].push(j-i+);
} sort(s+,s++cnt);
cnt = unique(s+,s++cnt) - (s+);
} void solve()
{
scanf("%d",&m);
for(int i = ; i<m; i++)
{
int x, ans;
scanf("%d",&x);
int t = sch(x); if(s[t]==x)
ans = q[x].top();
else if(t==)
ans = q[s[t]].top();
else
{
if(abs(x-s[t])==abs(x-s[t-]))
ans = max(q[s[t]].top(), q[s[t-]].top());
else if(abs(x-s[t])<abs(x-s[t-]))
ans = q[s[t]].top();
else
ans = q[s[t-]].top();
}
cout<<ans<<endl;
}
cout<<endl;
} int main()
{
#ifdef LOCAL
freopen("", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int T;
scanf("%d",&T);
while(T--)
{
init();
solve();
}
}

结构体:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
//#define LOCAL
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[];
int n, m, cnt; struct node
{
int val, len;
bool operator<(node &xx)const{
if(val==xx.val) return len>xx.len;
return val<xx.val;
}
}s[*]; void init()
{
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%d",&a[i]), a[i] = a[i]^a[i-]; cnt = ;
for(int i = ; i<=n; i++)
for(int j = i; j<=n; j++)
s[++cnt].val = a[i-]^a[j], s[cnt].len = j-i+; n = ;
sort(s+,s++cnt);
for(int i = ; i<=cnt; i++)
if(i== || s[i].val!=s[i-].val)
s[++n] = s[i];
} int sch(int x)
{
int l = , r = n;
while(l<r)
{
int mid = (l+r)>>;
if(s[mid].val>=x)
r = mid;
else
l = mid + ;
}
return r;
} void solve()
{
scanf("%d",&m);
for(int i = ; i<m; i++)
{
int x, ans;
scanf("%d",&x);
int t = sch(x); if(s[t].val==x)
ans = s[t].len;
else if(t==)
ans = s[].len;
else
{
if( abs(x-s[t].val)==abs(x-s[t-].val) )
ans = max( s[t].len, s[t-].len );
else if( abs(x-s[t].val)<abs(x-s[t-].val) )
ans = s[t].len;
else
ans = s[t-].len;
}
cout<<ans<<endl;
}
cout<<endl;
} int main()
{
#ifdef LOCAL
freopen("", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int T;
scanf("%d",&T);
while(T--)
{
init();
solve();
}
}

HDU5968 异或密码 —— 二分 + 边界的细节处理的更多相关文章

  1. [HDU5968]异或密码

    [HDU5968]异或密码 题目大意: 数据共\(T(T\le100)\)组.每组给定一个长度为\(n(n\le100)\)的非负整数序列\(A(A_i\le1024)\),\(m(m\le100)\ ...

  2. HDU-5968异或密码

    超级传送门 题目描述: 晨晨在纸上写了一个长度为N的非负整数序列{ai}.对于这个序列的一个连续子序列{al,al+1,…,ar}晨晨可以求出其中所有数异或的结果 alxoral+1xor...xor ...

  3. hdu_5968_异或密码(预处理+二分)

    题目链接:hdu_5968_异或密码 题意: 中午,不解释 题解: 前缀处理一下异或值,然后上个二分查找就行了,注意是unsigned long long #include<bits/stdc+ ...

  4. HDU 5968 异或密码

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  5. HDU 5968 异或密码 【模拟】 2016年中国大学生程序设计竞赛(合肥)

    异或密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Des ...

  6. 异或密码---hdu5968(CCPC合肥,二分)

     题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5968 思路:先把所有的连续异或值保存起来,排序,然后用二分找到距离x最近的那个点,判断即可:   # ...

  7. 【Java面试真题】剑指Offer53.2——0~n-1中缺失的数字(异或、二分两种解法)

    [Java实现]剑指Offer53.2--0~n-1中缺失的数字:面试真题,两种思路分享 前面有另一道面试题[Java实现]剑指offer53.1--在排序数组中查找数字(LeetCode34:在排序 ...

  8. HDU 1998 奇数阶魔方【模拟填数/注意边界和细节】

    奇数阶魔方 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  9. Wannafly Winter Camp 2020 Day 6H 异或询问 - 二分

    给定一个长 \(n\) 的序列 \(a_1,\dots,a_n\),定义 \(f(x)\) 为有多少个 \(a_i \leq x\) 有 \(q\) 次询问,每次给定 \(l,r,x\),求 \(\s ...

随机推荐

  1. Truck History(最小生成树)

    poj——Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27703   Accepted: 10 ...

  2. HDU 4349 Xiao Ming's Hope 找规律

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4349 Xiao Ming's Hope Time Limit: 2000/1000 MS (Java/ ...

  3. luogu P3811 【模板】乘法逆元

    题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下的逆元. 输入输出样例 输入样 ...

  4. linux jar 命令使用

    原文链接:http://blog.chinaunix.net/uid-692788-id-2681136.html JAR包是Java中所特有一种压缩文档,其实大家就可以把它理解为.zip包.当然也是 ...

  5. c++ concurrency serial 1: introduction

    platform: vs2012 Code#include <iostream> #include <thread> using namespace std; void Fun ...

  6. Android应用开发-小巫CSDN博客客户端开发开篇

    2014年9月8日 八月十五 祝各位中秋节快乐 小巫断断续续花了几个星期的时间开发了这么一款应用——小巫CSDN博客,属于私人定制的这样的一款应用,整个客户端的数据全部来自本人博客,是通过爬取本人博客 ...

  7. git extensions远程配置

    http://blog.csdn.net/pgmsoul/article/details/7860393 远程地址是如下格式:git@github.com:yaoname/project.git 保存 ...

  8. php程序调试: xdebug的配置

    怎样在phpeclipse中像调试Java程序一样调试php呢? XDebug的版本号非常多,打开http://xdebug.org/index.php.把站点细致看一下,你会发现有句"If ...

  9. const、typedef 、 define总结

    constkeyword const=read only,修饰的为仅仅读变量而不是常量.const修饰的变量不能用作数组的维数也不能放在switch语句的case:之后. 主要作用有: 1.通过把不希 ...

  10. logstash+es+kibana+redis搭建

    环境信息: CentOS 6.5 redis 3.0.4 logstash elasticsearch kibana 服务端ip:192.168.0.65 客户端ip:192.168.0.66 关系结 ...