您的位置:首页 > 其它

hdu_5792_World is Exploding(树状数组+逆序对)

2016-08-03 11:08 501 查看

题目链接:hdu_5792_World is Exploding

题意:

给你一个数列,让你找有多少个(a,b,c,d)满足a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.

题解:

如果abcd可以相等,那么就是所有的顺序对和逆序对相乘,但这里要不相等,所以我们减去相等的情况就行。

要满足Aa<Ab,Ac>Ad,考虑其中一个数Ai 然后我们可以发现,建立在Ai的顺序对和逆序上,bd不会相等,

所以我们只需要找出每一个Ai 前后顺序对和逆序对,然后对应交叉相乘,就是a=c的情况,然后总答案减去就行

#include<cstdio>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;

const int N=5E4+7;
int a
,n,idx
,len,tr
,t1
,t2
,t3
,t4
;

inline void add(int x,int c){while(x<=n)tr[x]+=c,x+=x&-x;}
inline int ask(int x){int an=0;while(x)an+=tr[x],x-=x&-x;return an;}

int getid(int x){return lower_bound(idx+1,idx+1+len,x)-idx;}

int main()
{
while(~scanf("%d",&n))
{
F(i,1,n)scanf("%d",a+i),idx[i]=a[i],tr[i]=0;
sort(idx+1,idx+1+n),len=1;
F(i,2,n)if(idx[i]!=idx[len])idx[++len]=idx[i];
ll zheng=0,ni=0,ans;
F(i,1,n)
{
int x=getid(a[i]);
int now=ask(x-1);
zheng+=now,t1[i]=now,t2[i]=ask(n)-ask(x),ni+=t2[i];
add(x,1);
}
F(i,1,n)tr[i]=0;
for(int i=n;i>=1;i--)
{
int x=getid(a[i]);
int now=ask(x-1);
t4[i]=now,t3[i]=ask(n)-ask(x);
add(x,1);
}
ans=zheng*ni;
F(i,1,n)ans-=t1[i]*t2[i]+t1[i]*t4[i]+t3[i]*t2[i]+t3[i]*t4[i];
printf("%lld\n",ans);
}
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: