HOJ 2275 Number sequence

题意:问你有多少个序列满足Ai < Aj > Ak and i < j < k.

思路:对每个数求它之前和之后分别有多少个个数比它小,两边相乘。最后求和。具体实现先用树状数组正序求,再反过来再用一遍树状数组。

代码:特别要注意的是题目中Ai的范围是从0开始,但是树状数组不能从0开始,所以统一加一处理。但是可惜的是题目并没有出现0这样的数据,让一些并不正确的代码过了。

 1 #include<stdio.h>
 2 #include<string.h>
 3 int lowbit(int x)
 4 {
 5     return x&-x;
 6 }
 7 const int N=5e4+111,Max=32769;
 8 int c[N],a[N],ans[N],n;
 9 void add(int i,int x)
10 {
11     i++;
12     while(i<Max)
13     {
14         c[i]+=x;
15         i+=lowbit(i);
16     }
17 }
18 int q(int i)
19 {
20     i++;
21     int sum=0;
22     while(i)
23     {
24         sum+=c[i];
25         i-=lowbit(i);
26     }
27     return sum;
28 }
29 int main()
30 {
31     while(scanf("%d",&n)!=EOF)
32     {
33         long long Ans=0;
34         memset(c,0,sizeof(c));
35         for(int i=1;i<=n;i++)
36         {
37             scanf("%d",&a[i]);
38             ans[i]=q(a[i]-1);
39             add(a[i],1);
40         }
41         memset(c,0,sizeof(c));
42         for(int i=n;i;i--)
43         {
44             Ans+=ans[i]*q(a[i]-1);
45             add(a[i],1);
46         }
47         printf("%lld
",Ans);
48     }
49     return 0;
50 }
原文地址:https://www.cnblogs.com/L-King/p/5448246.html