今天生日捏,嘻嘻~

题意:给定A B数组长度为n 求所有 (1<=i,j <=n ) a[i]+b[j] 的异或和。 n <=200000  ai bi <=228

这题比赛没写出来,而且完全没思路,结束后看了zz大佬的博客大致有了解题方向,然后再参考了cyc的...于是大致会写了。

由于xor 实际上是每一位的xor ,所以考虑一位一位的算出答案。(即算出答案在二进制下的每一位的数字 0 或 1)

ps:以下的每一个数都为二进制,位数从右往左数。

可以证明,已知  某一位上有 x 个 1  y 个0 的话, 这一位上xor后为 x mod 2。

这样就将问题转换为: 求所有 a[i]+b[j] 在二进制下,每一位分别的 1 的个数 之和。

举个栗子!

如样例

001 010

011 100

a[i]+b[j]分别为:

100

101

101

110

第1位有0 1 1 0 共2个 1   mod 2后为 0 (从左往右的第3位)

第2位有0 0 0 1 共1个 1   mod 2后为 1 (从左往右的第2位)

第3位有1 1 1 1 共4个 1   mod 2后为 0 (从左往右的第1位)

于是答案就是 (010)2=(2)10

然后就可以开始一位位的考虑了

当我们计算答案的第 k 位时,发现 a[i] b[j] 的k+1位之后的 (如当k=2 ,a[i]=100,那么k+1为之后的即 1)

对第k位的答案是没有作用的,因为当a[i]+b[j]后,k+1位之后的数对k没有任何影响。

所以就可以将k+1之后的都给扔掉。

于是我萌设

c[i]=a[i] and ((1 << k)-1)

d[i]=b[i] and ((1 << k)-1)

and ((1 << k)-1) 就相当于可以把k位都拿出来了

如 一个数10101110  k=4 那么

10101110  and

00001111

=00001110

至于为什么可以就自己思考一下。

由于0的个数是没有用的,所以考虑1就好了

发现0<=c[i],d[j]<  2k

对于第k位可以有一个 1

只有满足

①2k-1<=c[i]+d[j]<2这个就相当于

c[i]+d[j]没有向下一位进 1 而且第 k 位会是 1 因为 2k-1 相当于在第k位有一个1 其他都为0 而2k 相当于第k+1位有一个1其他都为0

这样的一个范围里就包含了所有第k位是1的所以数 ,而c[i]+d[j] 在这个范围里 所以说明对第 k 位有一个1 的贡献。

②2k+2k-1<=c[i]+d[j]<2k+1

类比第一个,这个就是对下一位进1 后的且第k为是1。

一样可以得到这样的一个范围能满足 第k+1位是1 且 第k位是1。

那到底有多少个c[i]+d[j] 是在以上的两个范围的其中一个

只要求出有多少个这样的数对 (i,j) 满足 c[i]+d[j] 是以上两个范围里的其中一个,问题就解决了(求出了有多少个1了)

考虑固定 j 移动 i

把c数组从小到大排序。

只要找到最左的 i (L)和最右的 i(R) 这样由于单调性 L~R 中的 i 都是满足条件的,所以 R-L+1即是1的个数。

所以分两类 分别计算出两类的个数加起来即可

而对于L R 用二分就好了。

这题是我接触的比较新的题,写详细些,自己因为二分一个小地方敲错了一直tle,以后要注意。

最后的话,生日快乐!

 1 var n:longint;
2  i,k:longint;
3 a,b,c,d:array[..]of int64;
m1:int64;
ans,x,y:int64;
procedure qs(l,r:longint);
var i,j,m,t:longint;
begin
i:=l;
j:=r;
m:=c[(l+r)>>];
repeat
while c[i]<m do inc(i);
while c[j]>m do dec(j);
if i<=j then
begin
t:=c[i];c[i]:=c[j];c[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs(l,j);
if i<r then qs(i,r);
end;
function find(x:int64):longint; //找到第一个 x>=c[i] 的 i。
var l,r,m:longint;
begin
l:=;
r:=n;
while l<=r do
begin
m:=(l+r)>>;
if c[m]<x then l:=m+ else r:=m-;
end;
exit(l);
end;
begin
read(n);
for i:= to n do
read(a[i]);
for i:= to n do
read(b[i]);
c[]:=-;
c[n+]:= << ;
for k:= to do
begin
x:= << k; //即x=2k
y:= << (k-); //即 y=2k-1
for i:= to n do
begin
c[i]:=a[i] and (x-);
d[i]:=b[i] and (x-);
end;
qs(,n); //排序C数组
m1:=; //m1表示答案的第k位有多少个1
for j:= to n do
begin
m1:=m1+find(x-d[j])-find(y-d[j]);
//满足第 k位是 1 的第一种情况 2k-1<=c[i]+d[j]<2k
//两边都减 d[j] 得 2k-1-d[j]<=c[i]<2k-d[j]
//也就是说对于 所有满足这个范围的c[i] 都能使第 k 位是 1 find(x-d[j])
//就是最右的 i+
      //(为什么有个+1?因为find找的是 >=的而范围只有 >,所以find会找到满足这个范围的最右的 i 的下一个)
//由于答案为 最右的i - 最左的i +1 (类似 r-l+1) 而find(x-d[j]) 多加了个 1 所以计算时不再 +1
//而是 find(x-d[j])-find(y-d[j]);
m1:=m1+n+-find(x+y-d[j]);
//这个就是第二种情况 类似于第一种就好啦
end;
if m1 and = then ans:=ans+y;
end;
writeln(ans);
end.

atcoder ARC092 D - Two Sequences 二分 & 二进制的更多相关文章

  1. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  2. AtCoder AGC007E Shik and Travel (二分、DP、启发式合并)

    题目链接 https://atcoder.jp/contests/agc007/tasks/agc007_e 题解 首先有个很朴素的想法是,二分答案\(mid\)后使用可行性DP, 设\(dp[u][ ...

  3. AtCoder - 4351 Median of Medians(二分+线段树求顺序对)

    D - Median of Medians Time limit : 2sec / Memory limit : 1024MB Score : 700 pointsProblem Statement ...

  4. Atcoder Beginner Contest 155D(二分,尺取法,细节模拟)

    二分,尺取法,细节模拟,尤其是要注意a[i]被计算到和a[i]成对的a[j]里时 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> ...

  5. 【codeforces】Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理

    题目链接 题目大意 有n个维度为m的向量,取其中两个进行合并,合并时每个维度取两者之间的较大者,得到的新的向量中,维度值最小者最大为多少 分析 首先最需要注意的是m的取值,m最大只有8 那么我们可以二 ...

  6. Atcoder 2444 - JOIOI 王国(二分)

    题面传送门 记 \(mxi\) 为 IOI 国海拔的最大值,\(mni\) 为 IOI 国海拔的最小值,\(mxj\) 为 JOI 国海拔的最大值,\(mnj\) 为 JOI 国海拔的最小值. 不难发 ...

  7. Atcoder arc092

    E-Both Sides Merger 给你一个序列,支持两种操作,直到序列中只有一个数时停下来,使得剩下数最大,并输出选数方案. 操作1:扔掉一个最前端或最后端的元素.操作2:选取一个不在边界上的元 ...

  8. D. Minimax Problem(二分+二进制)

    D. Minimax Problem time limit per test 5 seconds memory limit per test 512 megabytes input standard ...

  9. Atcoder Grand Contest 006 D - Median Pyramid Hard(二分+思维)

    Atcoder 题面传送门 & 洛谷题面传送门 u1s1 Atcoder 不少思维题是真的想不出来,尽管在 Atcoder 上难度并不高 二分答案(这我倒是想到了),检验最上面一层的数是否 \ ...

随机推荐

  1. Jetty源码学习-编译Jetty源码二三事

    工作小几个月了,JDK基础和web应用框架学的的差不多了,开始学习Jetty源码,费了小半天才编译成功,把自己拆过的坑记录下来. 编译前的环境: MAVEN 3.3.Eclips eLuna Serv ...

  2. kafka简介【转】

    一.为什么需要消息系统 () 解耦 在项目启动之初来预测将来项目会碰到什么需求,是极其困难的.消息系统在处理过程中间插入了一个隐含的.基于数据的接口层,两边的处理过程都要实现这一接口.这允许你独立的扩 ...

  3. CH5E07 划分大理石【多重背包】

    5E07 划分大理石 0x5E「动态规划」练习描述有价值分别为1..6的大理石各a[1..6]块,现要将它们分成两部分,使得两部分价值之和相等,问是否可以实现.其中大理石的总数不超过20000. 输入 ...

  4. 焦作网络赛E-JiuYuanWantstoEat【树链剖分】【线段树】

    You ye Jiu yuan is the daughter of the Great GOD Emancipator. And when she becomes an adult, she wil ...

  5. vs 开发常用快捷键

    alt+shift+enter    编辑区最大化ctrl+]        括号匹配 ctrl+j        强迫智能感知ctrl+shift+空格    强迫智能感知(参数) ctrl+k+d ...

  6. RAC 性能分析 - 'log file sync' 等待事件

    简介 本文主要讨论 RAC 数据库中的'log file sync' 等待事件.RAC 数据库中的'log file sync' 等待事件要比单机数据库中的'log file sync' 等待事件复杂 ...

  7. Day19 客户关系系统实战

    day19 今日内容 Service事务 客户关系管理系统     Service事务 在Service中使用ThreadLocal来完成事务,为将来学习Spring事务打基础! 1 DAO中的事务 ...

  8. (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务)

    (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务) 1.概念:隐式事务,显式事务,自动提交事务 2.操作:如何设置事务模式 3.存储过程中的事务 XACT_ABORT 1 ...

  9. mysql 表的增删改查 修改表结构

    四.修改表结构 语法: . 修改表名 ALTER TABLE 表名 RENAME 新表名; . 增加字段 ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…], ADD 字段名 ...

  10. mysql 数据操作 多表查询 子查询 带比较运算符的子查询

    带比较运算符的子查询 #比较运算符:=.!=.>.>=.<.<=.<> #查询大于所有人平均年龄的员工名与年龄 思路 先拿到所有人的平均年龄然后 再用另外一条sql ...