HDU-5792 World is Exploding(思维、树状数组+离散化)

题意:

给一个数列A,统计有多少个四元组(a, b, c, d)满足AAbAAd.(a != b != c != d)且a<b,c<d.

思路:

如果没有(a != b != c != d)的条件,那么问题其实就是统计A序列中逆序对和正序对个数然后相乘及是答案。

但是,现在这个条件存在表明多统计了(a == c || a == d || b == c || b == d)的情况,这几个情况限制下其它两个值是必定不会相等的,所以我们把ans减掉这些情况就好了。

我们需要预处理出lmi[i], lmx[i], rmi[i], rmx[i].

lmi[i]:[1, i-1]之间值比ai小的个数

lmx[i]:[1, i-1]之间值比ai大的个数

rmi[i]:[i+1, n]之间值比ai小的个数

rmx[i]:[i+1, n]之间值比ai大的个数

a == c时: ans -= rmx[i]*rmi[i].

a == d时: ans -= rmx[i]*lmx[i].

b == c时: ans -= lmi[i]*rmi[i].

b == d时: ans -= lmi[i]*lmx[i].


代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 5e5+5;
int n, cnt;
int a[maxn], b[maxn];
int c[maxn];
int lmx[maxn], lmi[maxn], rmx[maxn], rmi[maxn];
int lowbit(int x){return x&(-x);}
void update(int k)
{
	while(k <= cnt)
	{
		++c[k];
		k += lowbit(k);
	}
}
int query(int k)
{
	int ans = 0;
	while(k)
	{
		ans += c[k];
		k -= lowbit(k);
	}
	return ans;
}
int main()
{
	int cnt1, cnt2;
	while(~scanf("%d", &n))
	{
		for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), b[i] = a[i];
		sort(b+1, b+n+1);
		cnt = unique(b+1, b+n+1)-(b+1);
		for(int i = 1; i <= n; ++i)
		a[i] = lower_bound(b+1, b+cnt+1, a[i])-b;
		cnt1 = 0, cnt2 = 0;
		memset(c, 0, sizeof c);
		for(int i = 1; i <= n; ++i)
		{
			lmi[i] = query(a[i]-1);
			lmx[i] = query(cnt)-query(a[i]);
			cnt1 += lmx[i];
			cnt2 += lmi[i];
			update(a[i]);
		}
		memset(c, 0, sizeof c);
		for(int i = n; i >= 1; --i)
		{
			rmi[i] = query(a[i]-1);
			rmx[i] = query(cnt)-query(a[i]);
			update(a[i]);
		}
		LL ans = 1ll*cnt1*cnt2;
		for(int i = 1; i <= n; ++i)
		{
			ans -= 1ll*rmx[i]*rmi[i];
			ans -= 1ll*rmx[i]*lmx[i];
			ans -= 1ll*lmi[i]*rmi[i];
			ans -= 1ll*lmi[i]*lmx[i];
		}
		printf("%lld\n", ans);
	}
	return 0;
}


继续加油~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值