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 ...
随机推荐
- H5网页后在返回到微信公众平台自定义菜单
<p class="success">订阅成功!</p> <div class="btn" @click="finish ...
- C# Note37: Writing unit tests with use of mocking
前言 What's mocking and its benefits Mocking is an integral part of unit testing. Although you can run ...
- 第五章· Redis主从复制介绍
一.Redis主从复制 二.Redis主从复制工作机制 一.Redis主从复制 Redis复制功能简单介绍 1)使用异步复制.2)一个主服务器可以有多个从服务器.3)从服务器也可以有自己的从服务器.4 ...
- CodeForces 1151C Problem for Nazar
题目链接:http://codeforces.com/problemset/problem/1151/C 题目大意: 有一个只存奇数的集合A = {1, 3, 5……2*n - 1,……},和只存偶数 ...
- Monkey简介
Monkey简介 在Android的官方自动化测试领域有一只非常著名的“猴子”叫Monkey,这只“猴子”一旦启动,就会让被测的Android应用程序像猴子一样活蹦乱跳,到处乱跑.人们常用这只“猴子” ...
- SpringCloud实践引入注册中心+配置中心
随着服务数量的增多,尤其是多数项目涉及jni本地方法的调用,所需参数配置较多,同时内存溢出等维护问题时常发生.鉴于此,原tomcat集群的使用已难满足需求,而微服务的思想契合当前项目实践,特在服务端构 ...
- eclipse安装Activiti
一. eclipse自己下载 打开eclipse软件,然后点击菜单栏的help选项,选择install New Software,示例如下: 出现如下对话框: 点击添加[Add]按钮,出现如下对话框 ...
- hdu5238 calculator (线段树+crt)
(并不能)发现29393不是质数,而是等于7*13*17*19 于是可以用四个线段树分别维护模意义下,对x进行一个区间的操作后的值 最后再把这四个的答案用crt拼起来 也可以不crt,而是预处理0~2 ...
- BZOJ3456城市规划
题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.为了 ...
- [SDOI2011]消耗战(虚树)
洛古题面 题意:给定一棵树,割断每一条边都有代价,每次询问会给定一些点,求用最少的代价使所有给定点都和1号节点不连通 暴力\(DP\) 我们先考虑暴力怎么做 设\(dp[u]\)为以\(u\)为根的子 ...