UESTC -- 841 休生伤杜景死惊开(树状数组 逆序数)
2015-05-19 22:58
399 查看
题目大意:给出n个数,从左往右起代石堆的高度Ai,任何两堆较矮的石堆都能和它们之间的一座较高的石堆形成"八卦锁",将其中之人牢牢锁住,无从逃脱。求出这一串数有几个“八卦锁”;
思路分析:对于这个样例 1 2 3 4 1 ,能形成“八卦锁”的数是 “1 2 1”,“1 3 1”,“2 3 1”,“1 4 1”,“2 4 1”,“3 4 1”,可以发现,答案就是,每个数的(这个数之前比它小的数的个数与这个数之后比它小的数的个数的乘机)的和;
代码实现:
思路分析:对于这个样例 1 2 3 4 1 ,能形成“八卦锁”的数是 “1 2 1”,“1 3 1”,“2 3 1”,“1 4 1”,“2 4 1”,“3 4 1”,可以发现,答案就是,每个数的(这个数之前比它小的数的个数与这个数之后比它小的数的个数的乘机)的和;
代码实现:
#include<cstdio> #include<cstring> #include<iostream> #define Max(a,b) ((a)>(b)?(a):(b)) using namespace std; const int N=50010; int n,sum ,a ,b ,c ,maxn; int lowbit(int x){ return x&(-x); } void update(int i,int val){ while(i<=maxn){ sum[i]+=val; i+=lowbit(i); } } int getsum(int i){ int s=0; while(i>0){ s+=sum[i]; i-=lowbit(i); } return s; } int main(){ while(~scanf("%d",&n)){ long long ans=0; maxn=0; memset(sum,0,sizeof(sum)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(int i=1;i<=n;++i) scanf("%d",&a[i]),maxn=Max(maxn,a[i]); for(int i=1;i<=n;++i){ update(a[i],1); b[i]=getsum(a[i]-1); } memset(sum,0,sizeof(sum)); for(int i=n;i>=1;--i){ update(a[i],1); c[i]=getsum(a[i]-1); } for(int i=1;i<=n;++i) ans+=(b[i]*c[i]); printf("%lld\n",ans); } }
相关文章推荐
- UESTC 841 休生伤杜景死惊开(树状数组)
- cdoj841-休生伤杜景死惊开 (逆序数变形)【线段树 树状数组】
- UESTC 841 休生伤杜景死惊开 【线段树】
- cdoj 841 休生伤杜景死惊开 逆序数/树状数组
- 线段树或树状数组求逆序数
- hdu 2838 树状数组求逆序数及交换位置产生移动的数的和
- NYOJ117&& 树状数组求逆序数
- HDU2689 Sort it (树状数组求逆序数)
- poj 2299树状数组求逆序数
- poj3067 树状数组求逆序数
- 树状数组求逆序数
- hdu 1394 Minimum Inversion Number 树状数组求逆序数对(原理)
- HDU 2838 Cow Sorting(树状数组求逆序数)
- POJ3067 Japan(树状数组,逆序数)
- POJ 3067 Japan(树状数组求逆序数)
- hdu 2689 sort it(树状数组 逆序数)
- hdu 1394(树状数组求逆序数)
- POJ 2299 <离散化+树状数组求逆序数对>
- HDU 1394 - Minimum Inversion Number(树状数组求逆序数)
- POJ2299 树状数组求逆序数