这个题,对于每个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
//
//
//