题意是给定a数组,令s[i]表示从1到i中a[i]出现的次数,然后求二元组(i,j)的个数,使得1<=i<j<=n && s[i]>s[n-j+1]
求s[]用hash搞之最快了,但是cf 嘛……不敢用hash……一用肯定被人出数据hack
然后退而求其次二分搞之
统计用树状数组随便搞一下
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<set> #include<cstdlib> #include<map> #include<ctime> #define inf 1000000000 #define ll long long #define pa pair<ll,int> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll ans; int n; int a[1000005],disc[1000005],t[1000005],sum[1000005],now[1000005]; int find(int x) { int l=1,r=n; while(l<=r) { int mid=(l+r)>>1; if(disc[mid]<x)l=mid+1; else if(disc[mid]==x)return mid; else r=mid-1; } } int lowbit(int x) { return x&(-x); } void add(int x,int v) { for(int i=x;i<=n;i+=lowbit(i)) t[i]+=v; } int query(int x) { int sum=0; for(int i=x;i;i-=lowbit(i)) sum+=t[i]; return sum; } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=disc[i]=read(); sort(disc+1,disc+n+1); for(int i=1;i<=n;i++) a[i]=find(a[i]),sum[a[i]]++; for(int i=1;i<n;i++) { now[a[i]]++; add(now[a[i]],1); sum[a[i]]--; int t=query(n)-query(sum[a[i+1]]); ans+=t; } printf("%lld",ans); return 0; }