码迷,mamicode.com
首页 > 其他好文 > 详细

【CH4201】楼兰图腾

时间:2019-05-24 23:55:24      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:图片   close   表示   cst   span   har   show   getch   lld   

这道题我采用树状数组求解逆序对一类的思想解决

我们读入数据之后,分析问题,本题求解两个问题:‘^’的数量和‘v’的数量,我们先考虑^

假设我们令i为^的那个顶点,那么以i为顶点的^的个数就是i左侧高度小于i的高度的个数与右侧高度小于i的数量的乘积,我们只需要枚举i的位置,累加答案即可。

我们如何高效的维护i两侧小于i高度的数量?我们建立一个树状数组(当然线段树也可以)存储每一个高度出现的次数。

我们正序枚举i,对于每一个i,我们在树状数组中查找0~a[i]-1的数量,这个数量就是在i左侧高度小于i的高度的个数,查找完成后,我们将a[i]这个高度在树状数组中+1,表示出现过一次。

我们再进行一次逆序枚举,即可求出在i右侧高度小于i的数量。之后我们就可以求解^的数量

同理,我们也可以求解V的数量。

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int N=200010;
 8 int n,a[N],sum[N];
 9 ll ans,l[N],r[N];
10 inline int read() {
11     int ret=0;
12     int op=1;
13     char c=getchar();
14     while(c<0||c>9) {if(c==-) op=-1; c=getchar();}
15     while(c<=9&&c>=0) ret=ret*10+c-0,c=getchar();
16     return ret*op;
17 }
18 inline int lowbit(int x) {
19     return -x&x;
20 }
21 inline int query(int x) {
22     int ret=0;
23     while(x) {
24         ret+=sum[x];
25         x-=lowbit(x);
26     }
27     return ret;
28 }
29 inline void add(int x) {
30     while(x<=n) {
31         sum[x]++;
32         x+=lowbit(x);
33     }
34 }
35 int main() {
36     n=read();
37     for(int i=1;i<=n;i++) a[i]=read();
38     for(int i=1;i<=n;i++) {
39         l[i]=query(n)-query(a[i]);
40         add(a[i]);
41     }
42     memset(sum,0,sizeof(sum));
43     for(int i=n;i>=1;i--) {
44         r[i]=query(n)-query(a[i]);
45         add(a[i]);
46     }
47     for(int i=1;i<=n;i++)
48         ans+=(long long)l[i]*r[i];
49     printf("%lld ",ans);
50     ans=0;
51     memset(sum,0,sizeof(sum));
52     memset(l,0,sizeof(l));
53     memset(r,0,sizeof(r));
54     for(int i=1;i<=n;i++) {
55         l[i]=query(a[i]-1);
56         add(a[i]);
57     }
58     memset(sum,0,sizeof(sum));
59     for(int i=n;i>=1;i--) {
60         r[i]=query(a[i]-1);
61         add(a[i]);
62     }
63     for(int i=1;i<=n;i++)
64         ans+=(long long)l[i]*r[i];
65     printf("%lld",ans);
66     return 0;
67 }
AC Code

 

【CH4201】楼兰图腾

标签:图片   close   表示   cst   span   har   show   getch   lld   

原文地址:https://www.cnblogs.com/shl-blog/p/10920718.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!