2 i + 2 i + 1 < 2 i + 2 2^i+2^{i+1}<2^{i+2} 2i+2i+1<2i+2 ,所以组成三角形的边必定至少有两条相等,如
2 i + 1 + 2 i + 1 > 2 i + 1 2^{i+1}+2^{i+1}>2^{i+1} 2i+1+2i+1>2i+1。即小于等于 2 i + 1 2^{i+1} 2i+1的边都可以作为第三条边,那么就求出两条相等边的组合数,再与第三条边组合(等腰)。或者直接求三边组合数(等边)。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
const int M=3e5+5;
typedef long long ll;
ll a[M];
int main(){
int t; cin>>t;
while(t--){
int n; cin>>n;
map<ll,ll> mp;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]++;
}
ll sum=0; ll ans=0;
for(int i=0;i<=n;i++){
if(mp[i]>1) ans+=mp[i]*(mp[i]-1)/2*sum;
if(mp[i]>2) ans+=mp[i]*(mp[i]-1)*(mp[i]-2)/6;
sum+=mp[i];
}
cout<<ans<<endl;
}
}