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

题目链接:hdu_5968_异或密码

题意:

中午,不解释

题解:

前缀处理一下异或值,然后上个二分查找就行了,注意是unsigned long long

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4 typedef long long ll;
 5
 6 const int N=111;
 7 int t,dp[N],a[N],n,m,tp;
 8
 9
10 struct dt
11 {
12     int val,len;
13     bool operator<(const dt &b)const
14     {
15         return val<b.val;
16     }
17 }s[N*N],ttp;
18 bool cmp(dt a,dt b)
19 {
20     if(a.val==b.val)return a.len>b.len;
21     return a.val<b.val;
22 }
23 int main()
24 {
25     scanf("%d",&t);
26     while(t--)
27     {
28         scanf("%d",&n);
29         F(i,1,n)scanf("%d",a+i);
30         F(i,1,n)dp[i]=dp[i-1]^a[i];
31         int ed=0;
32         F(j,1,n)F(k,j,n)
33         {
34             s[++ed].val=dp[k]^dp[j-1];
35             s[ed].len=k-j+1;
36         }
37         sort(s+1,s+1+ed,cmp);
38         scanf("%d",&m);
39         F(i,1,m)
40         {
41             scanf("%d",&tp);
42             ttp.val=tp;
43             int now1=lower_bound(s+1,s+1+ed,ttp)-s,ans;
44             int now2=now1-1;
45             now2=lower_bound(s+1,s+1+ed,s[now2])-s;
46             if(now1>ed)now1=ed;
47             int n1=abs(s[now1].val-tp),n2=abs(s[now2].val-tp);
48             if(n1>n2)ans=now2;
49             else if(n1<n2)ans=now1;
50             else if(s[now1].len>s[now2].len)ans=now1;
51             else ans=now2;
52             printf("%d\n",s[ans].len);
53         }
54         puts("");
55     }
56     return 0;
57 }

时间: 2024-11-23 03:04:20

hdu_5968_异或密码(预处理+二分)的相关文章

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

异或密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description 晨晨在纸上写了一个长度为N的非负整数序列{ai}.对于这个序列的一个连续子序列{al,al+1,-,ar}晨晨可以求出其中所有数异或的结果 alxoral+1xor...xorar其 中xor表示位异或运算,对应C.C++. Java等语言中的^运算.小璐提出了M个询问,每个询问用

HDU 5968 异或密码

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: center; font-family: 宋体; color: rgb(26,92,200); font-weight: bold; fo

poj 3501 Escape from Enemy Territory 预处理+二分+bfs

传送门 给一个起点一个终点, 给出整个地图的宽和高, 给出n个敌人的坐标. 让你找到一条路径, 这条路径上的点距离所有敌人的距离都最短, 输出最短距离. 首先预处理出来地图上的所有点到敌人的最短距离, 然后二分距离, bfs就可以. tle了好多次, 到网上搜题解, 看到别人是先把敌人的坐标都存到数组里最后在一起预处理, 而我是读一个点处理一个点, 改了以后才ac....... 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define

51Nod 1010 只包含因子2 3 5的数 | 预处理+二分

Input示例 5 1 8 13 35 77 Output示例 2 8 15 36 80 分析:将所有的只含有2 3 5因子的数打一个表保存在一个数组里,然后二分查找第一个>=数组里的数,输出 #include <bits/stdc++.h> using namespace std; typedef long long LL; #define rep(i,a,n) for(int i = a; i < n; i++) #define repe(i,a,n) for(int i =

Codeforces Round #435 (Div. 2) E. Mahmoud and Ehab and the function(预处理+二分)

题目链接:点我点我 题意:公式:,给出n个数,从a[1]到a[n],和m个数(b数组),然后从b数组里挑出连续的n个数(也就m-n+1中选择),按公式计算,使得f最小, 还有q次对a数组的操作(某个区间增加值,减少值),求出最小值. 题解:显然对a数组的处理非常简单,一开始确定一定值,然后update的时候,判断一下奇偶性质就可以直接加了(前一项正后一项一定是负的,可以抵消). 然后就是b数组的处理了,一开始没处理好,一直在这边卡超时.先把b数组一项一项正负不同的加进去,然后再进行处理,得到c数

机房测试3:三角tri(dp预处理+二分+dfs剪枝)

题目: 分析: 考虑最暴力的暴搜,怎么才能优化呢? 如果我们确切地知道第k大的路径权值和有多大,那么在dfs里面加一个限制就可以求出所有前k大的路径了. 很显然答案是满足单调性的. 可以二分一个答案,dfs一遍,看满足这个答案的有多少条路径,如果超过k条,就往大的走. 最后把二分出来的答案跑一遍dfs,输出路径即可. 时间复杂度:O(log(n*n)*玄学dfs) #include<bits/stdc++.h> using namespace std; #define N 1005 #defi

hdu 4791 dp预处理+二分

题意: 打印东西,给出区间(张数)对应费用(到达一定张数就都按某更低的价格),m次询问,问最优费用.给的时候按张数递增给的. dp出当前张数到最后的最小值.对于询问q,然后二分处>=q的最小的一个张数的价格.min(这个价格*p,dp[这+1])即可.nlogn;后来看网上有些人用线段树,没必要的. ps:开始竟然因为犯中间数据爆int的初级错误!,不该不该! #include<iostream> #include<vector> #include<algorithm&

HDU 5042 GCD pair 预处理+二分 分段

点击打开链接 #include <stdio.h> #include <string.h> #include <iostream> #include <cmath> #include <algorithm> #include <vector> using namespace std; typedef long long ll; ll gcd(ll x, ll y){ if(x>y)swap(x,y); while(x){ y%=

HDU 5968:异或密码(暴力)

http://acm.hdu.edu.cn/showproblem.php?pid=5968 题意:中文题意. 思路:一开始不会做,后来发现数据范围很小,而且那个数要是连续的,所以可能把所有情况枚举出来很小吧.打了个表发现 100 只有 4950 个,然后直接暴力枚举每一种情况,放在Hash里面标记是否出现过这个数,再弄一个len数组放置每一种情况长度,然后对答案分别向左和向右找最长的长度就好了. 1 #include <cstdio> 2 #include <cstring> 3