1. 程式人生 > >codeforces817b Makes And The Product

codeforces817b Makes And The Product

Note

In the first example Makes always chooses three ones out of four, and the number of ways to choose them is 4.

In the second example a triple of numbers (1, 2, 3) is chosen (numbers, not indices). Since there are two ways to choose an element 3, then the answer is 2.

In the third example a triple of numbers (1, 1, 2)

 is chosen, and there's only one way to choose indices.

最小乘積必然是前3小的元素乘積

考慮第i個點的貢獻 如果ai∈前三小的元素,那麼他的貢獻就是1-(i-1)中第二元素個數*(i+1)-n中第三元素個數+1-(i-1)第三元素個數*(i+1)-n第二元素個數

注意long long與特判第二元素==第三元素

程式碼:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=300000+10;
int has[maxn];
int s[maxn],t[maxn];
int A[maxn],B[maxn];
int tot=0;
inline int bs(int x){
	int l=1,r=tot;
	while(l+1<r){
		int mid=(l+r)>>1;
		if(has[mid]>x)
			r=mid-1;
		else l=mid;
	}
	if(has[r]==x)
		return r;
	return l;
}
int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	int n;
	scanf("%d",&n);
	//n=100000;
	for(int i=1;i<=n;i++){
		scanf("%d",&A[i]);
		//A[i]=1;
		B[i]=A[i];
	}
	int x,y,z;
	sort(B+1,B+n+1);
	long long ans=0;
	for(int i=1;i<=n;i++)
		if(B[i]!=B[i-1])
			has[++tot]=B[i];
	x=bs(B[1]),y=bs(B[2]),z=bs(B[3]);
	for(int i=1;i<=n;i++){
		int u=bs(A[i]);
		t[u]++;
	}
	for(int i=1;i<=n;i++){
		int u=bs(A[i]);
		t[u]--;
		if(u==x){
			if(y==z)
				ans+=(long long)s[y]*t[z];
			else ans+=(long long)s[y]*t[z]+(long long)s[z]*t[y];
		}
		else if(u==y){
			if(x==z)
				ans+=(long long)s[x]*t[z];
			else ans+=(long long)s[x]*t[z]+(long long)s[z]*t[x];
		}
		else if(u==z){
			if(y==x)
				ans+=(long long)s[x]*t[y];
			else ans+=(long long)s[x]*t[y]+(long long)s[y]*t[x];
		}
		s[u]++;
	}
	cout<<ans<<endl;
return 0;
}