fzu 2058 问题转化 + 二分

题意

A array contain N number, can you tell me how many different pair i,j that satisfy a[i] + a[j] = M and 1<=i < j <=N.

0 < N <= 100000, 0 <= M <= 1000000000, -1000000000 <= a[i] <= 1000000000

思路:

用map记录会超时

所以想到手写二分。思考一下其实满足题目条件的对数和每个数字的位置并没有关系——排序+二分查找(范围来确定个数)即可。

code:

#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<cctype>
#include<cstdlib>
using namespace std;

#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define mod 1000000007
typedef pair<int,int> pii;
typedef long long LL;
//------------------------------
const int maxn = 200005;

int a[maxn];
int n,m;

int Scan(){
    int f=1, ret=0;
    char c;
    while((c=getchar())==' ' || c=='\n') ;
    if(c=='-') f=-1;
    else if(c!='+') ret+=c-'0';
    while((c=getchar())<='9' && c>='0')
        ret=ret*10+c-'0';
    return ret*f;
}
int main(){
    while(scanf("%d%d",&n,&m) != EOF){
        for(int i = 0; i < n; i++){
            a[i] = Scan();
        }
        sort(a,a+n);
        long long cnt = 0;
        for(int i = 0; i < n; i++){
            int id1 = lower_bound(a+i+1, a+n, m-a[i]) - a;
            int id2 = upper_bound(a+i+1, a+n, m-a[i]) - a;
            cnt += (id2 - id1);
        }
        cout << cnt << endl;
    }
    return 0;
}

一TLE吓得我都开挂了....T_T

时间: 2024-10-18 12:35:17

fzu 2058 问题转化 + 二分的相关文章

HDU 2675 Equation Again

公式转化+二分答案 首先,把题目中给的等式转化一下,变成了这个样子. 等式右边的值是可以求出来的. ln(x)/x的大致图像是这样的 那么只要对[0,e]和[e,+∞]分别进行二分答案即可. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; double Y,k; const double e=2.71828182845904

[数位dp+二分] fzu 1074 Nancy&#39;s Birthday

题意:给m,n,问含有m个0的第k个数,是几位数,并且最高位是多少. 思路:和普通数位dp一样,加上个二分. 然后就是注意一下,极限值测试下能否算出来,这题极限值很大! 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #

莫对算法/二分查找 FZU 2072 Count

题目传送门 1 /* 2 题意:问区间内x的出现的次数 3 莫队算法:用一个cnt记录x的次数就可以了 4 还有二分查找的方法 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include <cstring> 10 using namespace std; 11 12 const int MAXN = 1e5 + 10; 13 const int INF = 0x3

【转化,排序,二分】

问题描述 给定平面上n个点. 求两条直线,这两条直线互相垂直,而且它们与x轴的夹角为45度,并且n个点中离这两条直线的曼哈顿距离的最大值最小. 两点之间的曼哈顿距离定义为横坐标的差的绝对值与纵坐标的差的绝对值之和,一个点到两条直线的曼哈顿距离是指该点到两条直线上的所有点的曼哈顿距离中的最小值. 输入格式 第一行包含一个数n. 接下来n行,每行包含两个整数,表示n个点的坐标(横纵坐标的绝对值小于109). 输出格式 输出一个值,表示最小的最大曼哈顿距离的值,保留一位小数. 样例输入 41 00 1

FZU 2178 礼物分配 (折半搜索+二分)

题目地址:FZU 2178 由于n最大是30,一次全搜的话妥妥的超时,那么可以采用折半搜索.分成相同的两份,对左边的一堆进行预处理,然后再处理右堆,每一次都对左堆进行二分,找最接近的.由于两个人取的不能相差多于1个,所以要对每个个数分开存储.并排序,排序是为了后边的二分. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

Educational Codeforces Round 80 (Rated for Div. 2)【A,B,C,D】C题DP{GG了} D题【数组转化成二进制形式判断+二分】

A题直接暴力水过 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define int long long 5 #define N 6666666 6 int arr[N]; 7 8 signed main(){ 9 int _;cin>>_; 10 while(_--){ 11 int n,m; 12 cin>>n>>m; 13 if(n>=m){ 14 cout<<"

Gunner II(二分,map,数字转化)

Gunner II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1740    Accepted Submission(s): 635 Problem Description Long long ago, there was a gunner whose name is Jack. He likes to go hunting ve

FZU 11月月赛D题:双向搜索+二分

/* 双向搜索感觉是个不错的技巧啊 */ 题目大意: 有n的物品(n<=30),平均(两个人得到的物品差不能大于1)分给两个人,每个物品在每个人心目中的价值分别为(vi,wi) 问两人心目中的价值差最小是多少. 分析: 直接暴搜目测会超时 想到先搜索前一半,用数组a[0][i]保存第一个人在前半段取 i 个物品两个人的差的所有情况: 再搜索后一半保存两个人的差的相反数,用相同的规则保存在a[1][]中. 要想总差最小只需要 a[0][i]-a[1][num-i] (num=n/2或 n/2+1)

Problem FZU 2232 炉石传说(二分匹配)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2232 分析:因为是要求所有的学长一次性打败所有的敌人,所以可以看做是匹配问题.构建一个图,G[i][j]=1表示学长在攻击对手后,自己的生命值大于0,对方生命值小于等于0.然后看匹配数是否为n即可. #include <iostream> #include <stdio.h> #include <string.h> #include <string> #include