模擬賽 弱點(時間限制:2S;空間限制:256MB)

題目描述

一隊勇士正在向你進攻,每名勇士都有一個戰鬥值ai。但是這隊勇士卻有一個致命弱點,如果存在i<j<k使得ai>aj>ak,則會影響他們整體的戰鬥力。我們將這樣的一組(i,j,k)稱爲這隊勇士的一個弱點。請求出這隊勇士的弱點數目。

輸入

輸入文件:weakness.in
輸入的第一行是一個整數n,表示勇士的數目。
接下來一行包括n個整數,表示每個勇士的戰鬥值ai。

輸出

輸入文件:weakness.out
輸出爲一行,包含一個整數。表示這隊勇士的弱點數目。

輸入樣例

4
10 8 3 1

輸出樣例

4

數據範圍

對於30%的數據,3<=n<=100
對於100%的數據,3<=n<=1000000

對於100%的數據,1<=ai<=1000000,每個ai均不相同

題解

樹狀數組,枚舉中間點。兩邊像取逆序對一樣做即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define inf 1<<30
#define ll long long
#define MAXN 1000005
using namespace std;
int n,a[MAXN],maxs;
int tr[MAXN],p[MAXN],q[MAXN];
ll ans;
void init()
{
	scanf("%d",&n);
	int i;
	for(i=1;i<=n;i++)
	   {scanf("%d",&a[i]);
	    maxs=max(maxs,a[i]);
	   }
}
int lowbit(int x) {return x&(-x);}
int find(int x)
{
	int sum=0;
	for(;x<=maxs;x+=lowbit(x)) sum+=tr[x];
	return sum;
}
void insert(int x)
{
	for(;x>0;x-=lowbit(x)) tr[x]++;
}
void work()
{
	int i;
	for(i=1;i<=n;i++)
	   {p[i]=find(a[i]+1);
	    insert(a[i]);
	   }
	memset(tr,0,sizeof(tr));
	for(i=n;i>0;i--)
	   {q[i]=n-i-find(a[i]+1);
	    insert(a[i]);
	   }
	for(i=1;i<=n;i++) ans+=(ll)p[i]*q[i];
	printf("%I64d\n",ans);
}
int main()
{
	freopen("weakness.in","r",stdin);
	freopen("weakness.out","w",stdout);
	init(); work();
	return 0;
}

發佈了367 篇原創文章 · 獲贊 2 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章