RDay1-Problem 1 A
题目描述
给定一个长度为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的更多相关文章
- 1199 Problem B: 大小关系
求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...
- 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 ...
- C - NP-Hard Problem(二分图判定-染色法)
C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:262144 ...
- Time Consume Problem
I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- hdu1032 Train Problem II (卡特兰数)
题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能. (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...
- BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4032 Solved: 1817[Submit] ...
- [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 ...
- [LeetCode] The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- PHP curl报错“Problem (2) in the Chunked-Encoded data”解决方案
$s = curl_init(); curl_setopt($s, CURLOPT_POST, true); curl_setopt($s, CURLOPT_POSTFIELDS, $queryStr ...
随机推荐
- BS架构和CS架构的区别
C/S架构的优缺点: *优点: 1.客户端因为是独立设计,所以可以实现个性化 2.因为客户端是需要进行安装的,可以不需要重复安装和加载 3.因为客户端是独立开发的,所以有能力对客户端进行安全设计 4. ...
- go语言之行--golang操作redis、mysql大全
一.redis 简介 redis(REmote DIctionary Server)是一个由Salvatore Sanfilippo写key-value存储系统,它由C语言编写.遵守BSD协议.支持网 ...
- js04-DOM对象一
一.什么是HTML DOM HTML Document Object Model(文档对象模型) HTML DOM 定义了访问和操作HTML文档的标准方法 HTML DOM 把 HTML 文档呈现 ...
- Delphi Create(nil), Create(self), Create(Application)的区别
最近的项目中经常在程序中动态创建控件,势必用到Create. 但是随之而来的问题就是动态创建的控件是否可以正确的释放内存? 以及 Create(nil), Create(self), Create(A ...
- js对内容进行编码(富文本编辑器使用居多)
escape(string)函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串. 使用unescape(string) 对 escape() 编码的字符串进行解码.
- Python 面向对象高阶-----metaclass
Python 面向对象高阶-----metaclass 前言 类也是对象,既然类是对象,那就自然是某个东西的实例化,这个东西就是type 首先看下type是怎么回事 type type最常用的方法就是 ...
- [JSOI2008]Blue Mary开公司[李超线段树]
题面 bzoj luogu 好久以前听lxl讲过 咕掉了.. 竟然又遇到了 安利blog #include <cmath> #include <cstring> #includ ...
- C++:位操作基础篇之位操作全面总结
位操作篇共分为基础篇和提高篇,基础篇主要对位操作进行全面总结,帮助大家梳理知识.提高篇则针对各大IT公司如微软.腾讯.百度.360等公司的笔试面试题作详细的解答,使大家能熟练应对在笔试面试中位操作题目 ...
- virtual-dom
virtual-dom的历史 react最早研究virtual-dom,后来react火了之后,大家纷纷研究react的高性能实现,出现了2个流派,一是研究react算法的算法派,(virtual-d ...
- java 11 不可修改集合API
不可修改集合API 自 Java 9 开始,Jdk 里面为集合(List/ Set/ Map)都添加了 of 和 copyOf 方法,它们两个都用来创建不可变的集合,来看下它们的使用和区别. 示例1: ...