P1637 三元上升子序列

thair

好,这个naive的东西因为只有三元,很好求解。只要把每个数之前小的L[i]与之后大的R[i]求一下即可。

求两次逆序对即可。那么答案便是∑(L[i]*R[i]);

对于更高元的,胡雨菲写的是要用DP

那么先放水的一批的代码

(就这还洛谷蓝题,我直接给的黄题)

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 #define lowbit(a) (a&(-a))
 4 using namespace std;
 5 const int N = 30010;
 6 int x[N],tree[N],n,a[N],L[N],R[N];
 7 
 8 void add(int x,int v)
 9 {
10     if(x==0) return;
11     for(int i=x;i<=n;i+=lowbit(i)) tree[i]+=v;
12     return;
13 }
14 int getsum(int x)
15 {
16     if(x==0) return 0;
17     int ans=0;
18     for(int i=x;i>0;i-=lowbit(i)) ans+=tree[i];
19     return ans;
20 }
21 
22 
23 
24 int main()
25 {
26     scanf("%d",&n);
27     for(int i=1;i<=n;i++) scanf("%d",&a[i]),x[i]=a[i];
28     sort(x+1,x+n+1);
29     int k=0;
30     for(int i=1;i<=n;i++) if(x[i]!=x[i-1]) x[++k]=x[i];
31 
32     for(int i=1;i<=n;i++)
33     {
34         int p=lower_bound(x+1,x+k+1,a[i])-x;
35         L[i]=getsum(p-1);
36         add(p,1);
37     }
38     fill(tree+1,tree+n+1,0);
39     for(int i=n;i>=1;i--)
40     {
41         int p=lower_bound(x+1,x+k+1,a[i])-x;
42         R[i]=(n-i)-getsum(p);
43         add(p,1);
44     }
45     long long ans=0;
46     for(int i=1;i<=n;i++) ans+=L[i]*R[i];
47     printf("%lld",ans);
48     return 0;
49 }
AC代码:

 

posted @ 2018-04-03 13:27  huyufeifei  阅读(118)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜