• 【洛谷】【二分查找】P1102 A−B数对


    【题目描述:】

    给出一串数以及一个数字 C ,要求计算出所有 A−B=C 的数对的个数。(不同位置的数字一样的数对算不同的数对)

    【输入格式:】

    第一行包括 2 个非负整数 N 和 C ,中间用空格隔开。

    第二行有 N 个整数,中间用空格隔开,作为要求处理的那串数。

    【输出格式:】

    输出一行,表示该串数中包含的所有满足 A−B=C 的数对的个数。


    [算法分析:]

    对于前73%的数据,可以直接(O(N^2))枚举

    对于100%的数据,可以用二分优化到(O(nlog_2n))

    对于一个集合A,a∈A,b∈A

    求 a-b=c 的数对的个数,就是满足求出a=b+c的数对个数

    先把数据从小到大排序,

    枚举集合中的每一个元素b,二分找出第一个等于b+c的元素的位置pos1和第一个大于b+c元素的位置pos2

    则[pos1, pos2-1]区间内的每一个元素都能与b构成一个数对

    对于此时的b来说,能与其构成数对的方案数为pos2-pos1。


    [Code:]

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define re register
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 200000 + 1;
    
    int n, c, a[MAXN];
    LL ans;
    
    inline int abs(int x) {
    	return x>0 ? x : -x;
    }
    
    //炒鸡快读
    inline char gc()
    {
        static char buff[1000000],*S=buff,*T=buff;
        return S==T&&(T=(S=buff)+fread(buff,1,1000000,stdin),S==T)?EOF:*S++;
    }
    
    inline int read() {
    	int x = 0; char ch = gc();
    	while(!isdigit(ch)) ch = gc();
    	while(isdigit(ch))
    		x = (x << 3) + (x << 1) + ch - 48, ch = gc();
    	return x;
    }
    
    int main() {
    	n = read(), c = read();
    	for(re int i=1; i<=n; ++i) a[i] = read();
    	sort(a + 1, a + n + 1);
    	for(re int i=1; i<=n; ++i) {
    		int pos1 = lower_bound(a+1, a+n+1, a[i]+c)-a;
    		int pos2 = upper_bound(a+1, a+n+1, a[i]+c)-a;
    		ans += pos2-pos1;
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    数字图像-概述
    Python-python打包编译成pyd或者.so,保护代码。
    计算机组成原理-概述
    9大开源云管理平台(CMP)
    计算机组成原理-CPU-CPU知识科普:秒懂主频、核心、线程、缓存、架构详解
    svn git协同管理
    DEVTMPFS
    关于flash擦除的方法
    SQLServer强制保存
    360极速浏览器无法正确getHours
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9209902.html
Copyright © 2020-2023  润新知