小奇遐想

                                                     小奇遐想

题目描述

小奇望着青天中的悠悠白云,开始了无限的遐想,在它的视野中,恰好有n朵高度不同的白云排成一排,他想从左到右选出四朵白云a,b,c,d,使得h_a < h_b < h_d < h_c,即看起来像是彩虹的形状!它想知道有多少种方案数。

输入格式

第一行包括1个整数n。

第二行包括n个整数,第i 个正数表示h_i,保证这n个整数是n的一个全排列。

输出格式

输出一个整数表示答案。(mod 16777216)

样例

样例输入1

5
1 5 3 2 4

样例输出1

0

样例输入2

4
1 2 4 3

样例输出2

1

数据范围与提示

对于10%的数据n<=600;

对于40%的数据n<=5000;

对于100%的数据n<=200000。

 1 #include<cstdio>
 2 const int maxn=200000+10,mod=16777216;
 3 typedef long long ll;
 4 int h[maxn];
 5 ll c[maxn],l[maxn],r[maxn],z[maxn],lsum[maxn];
 6 int n;
 7 void update(int x,int w){
 8     while(x<=n){
 9         c[x]+=w;
10         x+=x&(-x);
11     }
12 }
13 ll query(int x){
14     ll ans=0;
15     while(x){
16         ans+=c[x];
17         x-=x&(-x);
18     }
19     return ans;
20 }
21 void update1(int x,int w){
22     while(x<=n){
23         z[x]+=w;
24         x+=x&(-x);
25     }
26 }
27 ll query1(int x){
28     ll ans=0;
29     while(x){
30         ans+=z[x];
31         x-=x&(-x);
32     }
33     return ans;
34 }
35 int main(){
36     scanf("%d",&n);
37     for(int i=1;i<=n;i++) scanf("%d",&h[i]);
38     ll ans=0;
39     for(int i=1;i<=n;i++){
40         update(h[i],1);
41         l[i]=query(h[i]-1);
42         r[i]=n-h[i]-i+l[i]+1;
43         update1(h[i],l[i]);
44         lsum[i]=query1(h[i]-1);
45     }
46     for(int i=2;i<=n-2;i++) ans=(ans+l[i]*r[i]*(r[i]-1)/2)%mod;
47     for(int i=3;i<=n-1;i++){
48         ans=(ans-lsum[i]*r[i]+mod)%mod;
49         if(ans<0) ans+=mod;
50     }    
51     printf("%lld\n",ans);
52     return 0;
53 }
View Code

 

posted @ 2020-07-28 16:47  ddoodd  阅读(130)  评论(0编辑  收藏  举报