hiho 1607 H星人社交网络 [Offer收割]编程练习赛31 Problem A 二分乱搞

这个题,对于每个A[i],题目都给出了3个否定的区间,是不能交朋友的,本来我想用容斥,1+2+3-12-13-23+123这样子写了一发然后WA了,后来发现没那么麻烦,每个人的交友区间都能求出一个单一的区间来[v1,v2],v1的值可以由第一条规则的出来,v2的值就是第二第三条规则的临界值的min,然后如果自己在这个区间里,给去掉就行了。

找的过程中用upper和lower bound非常方便。

整体复杂度是O(n*logn)

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <bits/stdc++.h>
using namespace std;

int N;
int A[100009];

int main(){
    cin>>N;
    for(int i=0;i<N;i++){
        scanf("%d",&A[i]);
    }
    sort(A,A+N);
    long long ans=0;
    for(int i=0;i<N;i++){


        int v1;
        if(A[i]/8*8==A[i]){
            v1=A[i]/8+8;
        }
        else{
            v1=A[i]/8+9;
        }

        int v2=8*A[i]+8;

        if(A[i]<88888){
            v2=min(v2,88888);
        }

        int curans=upper_bound(A,A+N,v2)-lower_bound(A,A+N,v1);
        if(A+i>=lower_bound(A,A+N,v1)&&A+i<upper_bound(A,A+N,v2))curans-=1;
        curans=max(0,curans);
        ans+=curans;


    }
    cout<<ans<<endl;


    return 0;
}

//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//
//


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值