题目链接: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. Codechef FNCS Chef and Churu

    Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...

  2. 支持C++11标准

    设置CB下的GCC. Settings->Compiler->Compiler Settings勾选Have g++ follow the C++11 ISO C++ language s ...

  3. .net 哈希

    using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptograph ...

  4. 【hibernate postgresql】注解@TypeDef/@Enumerated/数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" is of type gender but expression is of type character varying

    数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" ...

  5. cocos2d-x step by step(3) Doub le Kill简单的一些小动画

    在触控厮混了两年多,不过达到了自己的初衷以及目的. 目前从事cocos2d的更改和调优移植工作. 1 简单的一个图片放大和缩小 auto sprite = Sprite::create("l ...

  6. Segmentation fault(core dumped) 调试

    ReadingList: https://mytechrants.wordpress.com/2009/05/22/debugging-a-segmentation-fault-using-gdb/ ...

  7. Raid分类说明 (from mongodb权威指南)

    RAID(Redundant Array of Independent Disk,独立磁盘冗余阵列,旧称Redundant Array of InexpensiveDisk,廉价磁盘冗余阵列) 是一种 ...

  8. 利用Python自动发送邮件

    # -*- coding:utf-8 -*-from email.mime.text import MIMETextfrom email.header import Headerimport smtp ...

  9. Odoo HRMS应用简介

    Odoo HRMS包含行政管理的大部分功能,包含 部门组织架构 员工清册 岗位规划以及招聘管理 用工合同 考勤管理 休假和加班 费用报销 员工考核 绩效.激励.培训成绩 薪资清册     个角色 角色 ...

  10. Linux中du和df

    Linux运维过程中,常常发现du和df返回值不一样,偶尔会发现区别非常大. 特定情况下,可能df看到磁盘已满,可是du推断磁盘剩余空间非常大. 文件系统分配当中的一些磁盘块用来记录它自身的一些数据. ...