题目描述

给定一个长度为n的正整数序列a[i],计算出有多少个i<j的数对,a[i]+a[j]为二的次幂,也就是说存在一个正整数x满足a[i]+a[j]==2^x。

输入

输入文件A.in。

第一行一个整数n。

第二行n个整数,其中第i个整数为a[i]。

输出

输出文件A.out。

一行一个整数表示数对的数量。

样例输入

4
7 3 2 1

样例输出

2

【样例输入2】

3
1 1 1

【样例输出2】

3

【数据范围】

对于 20% 数据 $ n \le 10^3 $

对于 50% 数据 $ n \le 5 \times 10^4 , 0 \le a_i \le 10^9 $

对于 100% 数据 $ n \le 10^6 , 0 \le a_i \le 10^9 $

这个题之前想枚举二的整次幂,然后二分查找判断来着....

于是代码长这样:

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define lowbit(x) ( - x & x )
#define ll long long const int N = 1e6 + 5 ; int n,v[N];
ll ans;
ll mi[N]; inline int read(){
int x = 0 , f = 1 ;char ch = getchar () ;
while(ch < '0' || ch > '9'){if(ch == '-') f = - 1 ;ch = getchar () ;}
while( ch >= '0' && ch <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( ch ^ 48 ) ;ch = getchar () ;}
return f * x ;
} inline bool check ( int l , int r , int val ){
#define mid ( ( l + r ) >> 1 )
while( l <= r ){
if( v[mid] == val ) return true ;
if( v[mid] > val ) r = mid - 1 ;
if( v[mid] < val ) l = mid + 1 ;
}
#undef mid
return false ;
} int main(){
n = read () ;mi[0] = 1 ;
for(int i = 1 ; i <= 33 ; ++ i ) mi[i] = ( mi[i - 1] << 1 ) ;
for(int i = 1 ; i <= n ; ++ i ) v[i] = read () ;
std::sort( v + 1 , v + n + 1 );
for(int i = 1 ; i <= n ; ++ i ){
int dir = std::upper_bound( mi + 1 , mi + 33 + 1 , v[i] ) - mi ;
int tmp = mi[dir] - v[i];
if( check( i , n , tmp ) ) ++ ans ;
}
printf("%lld\n" , ans );
return 0;
}

显然这个做法会T到飞起!

那么我就想怎么消 $ log $ 然后旁边的 $ wqy \ 大\ 佬\ && zs \ 大\ 佬\ $ 告诉我可以用双指针来优化,做到消除 $ log $

然后我冥思苦想,终于和 \(DYJ\) 在一番激烈争论后确定了这题的双指针怎么搞,于是就AC了

具体思路也不怎么难,大体就是先排一遍序,然后枚举二的整次幂,双指针扫区间,统计答案

扫区间的时候,不断地根据单调性移动指针就好了

要特判一坨一样的值,因为扫到一坨一样的值是可以直接 \(\Theta(1)\) 算出来的,完全不必要去扫

于是,代码长这样:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cctype>
#define Noip2018RPINF return 0
#define Ll long long const int N = 1e6 + 3;
LL a[N];
int n,p[33]; inline int read(){
int v = 0,c = 1;char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-') c = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
v = ( v << 3 ) + ( v << 1 ) + ( ch ^ 48 );
ch = getchar();
}
return v * c;
}
int main(){
n = read();
p[0] = 1;
long long ans = 0;
for(int i = 1;i <= 30;++i) p[i] = p[i - 1] << 1;
for(int i = 1;i <= n;++i) a[i] = read();
std::sort(a + 1,a + n + 1) ;
for(int j = 30;j >= 0;--j){
int l = 1,r = n ;
while(l < r){
while(a[l] + a[r] > (long long)p[j]) -- r ;
while(a[l] + a[r] < (long long)p[j]) ++ l ;
if(l >= r) break ;
if(a[l] == a[r]){if(a[l] + a[r] == (long long)p[j]) ans += (long long)(r - l + 1) * (r - l) / 2;break ;}
int ll = l,rr = r ; long long sum1 = 0,sum2 = 0;
if(a[ll] + a[rr] == (long long)p[j]){
while(a[ll] == a[l]) ++ sum1 , ++ ll ;
while(a[rr] == a[r]) ++ sum2 , -- rr ;
}
ans += sum1 * sum2 ; l = ll , r = rr ;
}
}
printf("%lld\n",ans);
Noip2018RPINF;
}

RDay1-Problem 1 A的更多相关文章

  1. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  2. No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

    Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...

  3. C - NP-Hard Problem(二分图判定-染色法)

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  4. Time Consume Problem

    I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...

  5. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  6. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  7. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

  8. [LeetCode] Water and Jug Problem 水罐问题

    You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...

  9. [LeetCode] The Skyline Problem 天际线问题

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...

  10. PHP curl报错“Problem (2) in the Chunked-Encoded data”解决方案

    $s = curl_init(); curl_setopt($s, CURLOPT_POST, true); curl_setopt($s, CURLOPT_POSTFIELDS, $queryStr ...

随机推荐

  1. Oracle物化视图的创建及使用

    oracle物化视图 一.oracle物化视图基本概念  物化视图首先需要创建物化视图日志,  oracle依据用户创建的物化视图日志来创建物化视图日志表,  物化视图日志表的名称为mlog$_后面跟 ...

  2. java多线程中 volatile与synchronized的区别-阿里面试

    volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...

  3. Linux磁盘空间被未知资源耗尽

      在linux中,当我们使用rm在linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄,那么linux内核还是不会释放这个文件的磁盘空间,最后造成磁盘空间占用100%, ...

  4. DIV正确打开方式 ~~~~哈哈哈

    <div style='margin-left:25px;margin-right:25px;margin-top:10px;height:350px;min-height:50px;backg ...

  5. JQ初级

    一.认识jQuery 1.什么是jQuery jQuery是对原生JavaScript二次封装的工具函数集合 jQuery是一个简洁高效的且功能丰富的JavaScript工具库 2.jQuery的优势 ...

  6. jzoj6099. 【GDOI2019模拟2019.4.1】Dist

    题目链接:https://jzoj.net/senior/#main/show/6099 考虑直接统计某个点到其它所有点的距离和 我们先把整个团当成一个点建图,处理出任意两个团之间的距离\(dis(i ...

  7. 爬虫,基于request,bs4 的简单实例整合

    简单爬虫示例 爬取抽屉,以及自动登陆抽屉点赞 先查看首页拿到cookie,然后登陆要携带首页拿到的 cookie 才可以通过验证 """""" ...

  8. python学习day12 函数Ⅳ (闭包&内置模块)

    函数Ⅳ (闭包&内置模块) 1.内置函数(补充) lambda表达式也叫匿名函数. 函数与函数之间的数据互不影响,每次运行函数都会开一个辟新的内存. item = 10 def func(): ...

  9. nowcoder16450 托米的简单表示法

    题目链接 思路 仔细理解一下题意可以发现. 对于每个完整的括号序列都是独立的,然后就想到分治.高度是序列中所有括号序列的最大值,宽度是所有括号序列宽度和\(+1\). 然后仔细想了一下,这种分治应该是 ...

  10. HTML编辑器KindEditor

    KindEditor 是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(textarea)替换为可视化的富文本 ...