您的位置:首页 > 其它

Hdu-5792 World is Exploding(简单容斥)

2016-08-03 10:55 441 查看
[align=left]Problem Description[/align]
Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies:a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.
 

[align=left]Input[/align]
The input consists of multiple test cases.

Each test case begin with an integer n in a single line.

The next line contains n integers A1,A2⋯An.
1≤n≤50000
0≤Ai≤1e9
 

[align=left]Output[/align]
For each test case,output a line contains an integer.
 

[align=left]Sample Input[/align]

4
2 4 1 3
4
1 2 3 4

 

[align=left]Sample Output[/align]

1
0

 

题意:给你一个序列,问你有几个四元组(a,b,c,d) 满足:a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.

分析:求出整个序列顺序逆序对数之后,两数相乘,这是得到的方案数中包含一些三元组,需要把它们减掉。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
#define INF 0x3f3f3f 3f
#define eps 1e-9
struct thing
{
int val,num;
thing (int x,int y)
{
val = x;
num = y;
}
thing () {}
friend bool operator < (thing a,thing b)
{
return a.val < b.val;
}
}s[100005];
int n,now,a[100005];
long long ls[100005],ln[100005],rs[100005],rn[100005],f[100005];
long long ans,temp,s_sum,n_sum;
int lowbit(int x)
{
return x & (-x);
}
void Insert(int x)
{
while(x <= now)
{
f[x] += 1;
x += lowbit(x);
}
}
long long  Find(int x)
{
long long ans = 0;
while(x)
{
ans += f[x];
x -= lowbit(x);
}
return ans;
}
using namespace std;
int main()
{
while(~scanf("%d",&n))
{
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
s[i] = thing(a[i],i);
}
sort(s+1,s+1+n);
now = 0;
for(int i = 1;i <= n;i++)
{
if(i == 1 || s[i].val != s[i-1].val) now++;
a[s[i].num] = now;
}
memset(f,0,sizeof(f));
for(int i = 1;i <= n;i++)
{
ls[i] = Find(a[i]-1);
ln[i] = i - 1 - Find(a[i]);
Insert(a[i]);
}
memset(f,0,sizeof(f));
for(int i = n;i;i--)
{
rs[i] = n - i - Find(a[i]);
rn[i] = Find(a[i]-1);
Insert(a[i]);
}
ans=0;
temp=0;
s_sum=0;
n_sum=0;
for(int i=1;i<=n;i++)
{
s_sum+=rs[i];
n_sum+=rn[i];
temp+=rs[i]*rn[i]+rs[i]*ln[i]+ls[i]*rn[i]+ls[i]*ln[i];
}
ans=s_sum*n_sum;
ans-=temp;
printf("%I64d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: