CF459D

Pashmak and Parmida's problem

题面翻译

  • 给出长度为 \(n(1\le n\le10^6)\) 的序列 \(a(1\le a_i\le10^9)\)
  • \(f(i,j,x)\) 表示 \(a_i\dots a_j\)\(x\) 的出现次数。
  • 求有多少对 \(i,j\) 满足 \(f(1,i,a_i) > f(j,n,a_j)\)\(i < j\)

输入格式

The first line of the input contains an integer $ n $ $ (1<=n<=10^{6}) $ . The second line contains $ n $ space-separated integers $ a_{1},a_{2},...,a_{n} $ $ (1<=a_{i}<=10^{9}) $ .

输出格式

Print a single integer — the answer to the problem.

样例 #1

样例输入 #1

7
1 2 1 1 2 2 1

样例输出 #1

8

样例 #2

样例输入 #2

3
1 1 1

样例输出 #2

1

样例 #3

样例输入 #3

5
1 2 3 4 5

样例输出 #3

0
首先可以预处理f(1,i,a[i]) f(j,n,a[j])
然后考虑类似逆序对的求法
对于每个j 只有i<j 且g[j]的值在[1,f[i]-1]才满足
所以倒序枚举i
每次统计tot+=query(f[i]-1)
再更新add(g[i],1)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[1000005],b[1000005],m;
int tr[1000005*2];
int f[1000005],g[1000005],cnt[1000005],tot;
int lowbit(int x)
{
	return x&(-x);
}
void add(int p,int x)
{
	for(;p<=n;p+=lowbit(p))
		tr[p]+=x;
}
int query(int p)
{
	int sum=0;
	for(;p;p-=lowbit(p))
		sum+=tr[p];
	return sum;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
	sort(b+1,b+n+1);
	int m=unique(b+1,b+n+1)-(b+1);
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+m+1,a[i])-b;
	for(int i=1;i<=n;i++)
	{
		cnt[a[i]]++;
		f[i]=cnt[a[i]];
	}
	memset(cnt,0,sizeof(cnt));
	for(int i=n;i>=1;i--)
	{
		cnt[a[i]]++;
		g[i]=cnt[a[i]];
	}
	for(int i=n;i>=1;i--)
	{
		tot+=query(f[i]-1);
		add(g[i],1);
	}
	cout<<tot<<"\n";
	return 0;
}
posted @ 2023-01-17 14:29  PKU_IMCOMING  阅读(6)  评论(0)    收藏  举报