hdu2838

http://acm.hdu.edu.cn/showproblem.php?pid=2838

思路:对于数据3,4,1,2

先按顺序建树,updata(a[i],a[i]),s+=a[i];
当i=3时,1前面有3,4比1大,这时,先求出比1等于或小的元素和,在用s-sum(1),结果为,1前面比1大的元素和。

代码:

View Code
 1 #include<iostream>

 2 using namespace std;

 3 __int64 a[100005],c[100005],d[100005],n;

 4 int lowbit(int x)

 5 {

 6     return x&(-x);

 7 }

 8 __int64 sumc(int x)

 9 {

10     __int64 s=0;

11     while(x>0)

12     {

13         s+=c[x];

14         x-=lowbit(x);

15     }

16     return s;

17 }

18 __int64 sumd(int x)

19 {

20     __int64 s=0;

21     while(x>0)

22     {

23         s+=d[x];

24         x-=lowbit(x);

25     }

26     return s;

27 }

28 void updata(int i,int j)

29 {

30     while(i<=n)

31     {

32         c[i]+=1;

33         d[i]+=j;

34         i+=lowbit(i);

35     }

36 }

37 int main()

38 {

39 

40     while(scanf("%I64d",&n)>0)

41     {

42         memset(a,0,sizeof(a));

43         memset(c,0,sizeof(c));

44         memset(d,0,sizeof(d));

45         __int64 s=0,count=0;

46         for(int i=1;i<=n;i++)

47         {

48             scanf("%d",&a[i]);

49             updata(a[i],a[i]);

50             count+=a[i];               //a[1]~~a[i]之和

51             s+=(i-sumc(a[i]))*a[i];    //a[i]与前面比a[i]大的数交换的次数*a[i]

52             s+=count-sumd(a[i]);     //a[1]~~a[i]的总和-a[i]前面比a[i]小的数之和

53         }

54         printf("%I64d\n",s);

55     }

56     return 0;

57 }

 

你可能感兴趣的:(HDU)