hoj2275: Number sequence

hoj2275: http://acm.hit.edu.cn/hoj/problem/view?id=2275

题意:给一个数列,问有多少组满足:三个数Ai < Aj > Ak 且 i < j < k.

解法:树状数组:用数组left存储所有比左边的数小的数的个数,则结果为left值*(所有比右边的数小的数的个数)

code:

#include<iostream>
#include<cstdlib>
#include<cstdio>
int num[50010],c[50010],left[50010];
long long s;
int lowbit(int x)
{
    return x&(-x);
}
int sum(int x)
{
    int ss=0;           //ss为所有比x小的数的个数,因为顺序枚举(边输入边枚举),所以只表示所有比x小且在x左边的数的个数
    while(x>0)
    {
        ss+=c[x];
        x-=lowbit(x);
    }
    return ss;
}
void modify(int x)     //讲x插入
{
    while(x<50010)
    {
        c[x]++;            //c[x]为x的个数
        x+=lowbit(x);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(c,0,sizeof(c));       //初始化为0
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            left[i]=sum(num[i]-1);     //注意要减一,因为是小于,不包含与本身相等的数
            modify(num[i]);
        }
        memset(c,0,sizeof(c));         //注意要重新初始化为0
        s=0;
        for(int i=n;i>=1;i--)
        {
            s=s+sum(num[i]-1)*left[i];    //即s=s+right[i]*left[i]
            modify(num[i]);
        }
        printf("%lld\n",s);
    }
}
/*input:
5
1 2 3 4 1
output:
6*/

posted on 2012-08-09 14:39  acmer-jun  阅读(181)  评论(0编辑  收藏  举报

导航