zoukankan      html  css  js  c++  java
  • CF1166C A Tale of Two Lands

    题目链接:https://www.luogu.org/problemnew/show/CF1166C

    思路:

    当满足:

    $|a_i-a_j|<=|a_i|,|a_j|<=|a_i+a_j|$

    即为一种可行方案。

    不难发现以下结论:

    1.$a_i$的正负性对答案没有影响。

    2.基于结论$1$,对于条件$|a_i|,|a_j|<=|a_i+a_j|$是始终满足的。

     我们假设$a_j<a_i$。

    因为:

    $|a_i-a_j|<=|a_j|$

    则:

    $a_i<=2 imes a_j$

    由于原序列顺序对答案没有影响,我们可以按照升序排序,然后枚举$a_j$。在原序列中寻找一个最大的$k(k in [i+1,n])$,使得$a_k<=2 imes a_j$,此过程可使用二分查找。

    每次的答案显而易见是$k-i$,累加即可。

    代码:

    #include <bits/stdc++.h>
    static const int MAXN=200050;
    typedef long long ll;
    using namespace std;
    ll n,x,num,l,r,k,ans,a[MAXN];
    inline int get_abs(int x){
        return x>0?x:-x;
    }
    inline bool check(int x,int y){
        return a[x]<=(a[y]<<1);
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>x;
            a[++num]=get_abs(x);
        }
        sort(a+1,a+num+1);
        for(int i=1;i<=num;i++){
            l=i+1,r=num,k=-1;
            while(l<=r){
                int mid=(l+r)>>1;
                if(check(mid,i)){
                    k=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            if(k!=-1) ans+=k-i;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    并查集
    结构体字节对齐
    Dijkstra算法(单源最短路径)
    图的遍历
    二叉树的非递归遍历
    浅谈C语言中的联合体
    二叉排序(查找)树
    KMP算法
    C语言文件操作解析(四)
    Trie树
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/10920510.html
Copyright © 2011-2022 走看看