图腾计数

图腾计数


【Description】
whitecloth 最近参观了楼兰图腾。图腾的所在地有一排 N 个柱子,N
个柱子的高度恰好为一个 1 到 N 的排列,而楼兰图腾就隐藏在这些
柱子中。
由于 whitecloth 弱爆了,他只知道图腾由 3 个柱子组成,这三个柱子
组成了下凸或上凸的图形(>.<),所谓下凸,设三个柱子的高度从左
到右依次为 h1,h2,h3,那么 h1>h2,h3>h2,上凸则满足 h1<h2,
h3<h2。
现在 whitecloth 也找不到图腾具体是哪三个柱子,他只想知道满足这
两个形状的柱子有几组。
【Input】
第一行一个数 N
接下来一行 N 个数,依次表示每个柱子的高度
【Output】
一行两个数,表示下凸形状的数量和上凸形状的数量,用空格隔开
【Sample Input】
5
1 5 3 2 4
【Sample Output】
3 4
【Hint】对于 30%的数据,N<=100
对于 100%的数据,N<=200000

 

这道题其实就是一道裸的树状数组,知道一个柱的高度,他左边比他矮的个数乘以右侧比他矮的就是以他为中间柱的上凸形,同理可求得下凹形的。关键是知道怎么样计算出这些数值,没扫到一个位置,将他的高度压入树状数组,之后扫到一个位置i,lowbit(height(i))就知道了他左侧有多少比他矮,一共height(i)-1个比他矮的,也就知道了右边有多少比他矮,左侧一共i-1个数中有多少个比他矮知道了,左侧有多少个比他高也就知道了,右侧高的也就知道了,综上所述,可得到ANS。(中间过程记得开long long)。

 1 #include<cstdio>
 2 #define MAXN 200050UL
 3 #define LL long long
 4 using  namespace std;
 5  
 6 int n,sum[MAXN],h[MAXN];
 7 int ni[MAXN];
 8 LL aa,at;
 9  
10 int lowbit(int x){
11     return x&(-x);
12 }
13 void update(int x){
14     while(x<=n){
15         sum[x]+=1;
16         x+=lowbit(x);
17     }
18     return ;
19 }
20 int query(int x){
21     int fec=0;
22     while(x>0){
23         fec+=sum[x];
24         x-=lowbit(x);
25     }
26     return fec;
27 }
28  
29 int main(){
30 //  freopen("count.in","r",stdin);
31 //  freopen("count.out","w",stdout);
32     scanf("%d",&n);
33     for(int i=1;i<=n;i++){
34         scanf("%d",&h[i]);
35         ni[i]=h[i]-query(h[i]);
36         int t=query(h[i]);
37         at+=(LL)t*(LL)(h[i]-1-t);
38         aa+=(LL)(i-1-t)*(LL)(n-h[i]-i+1+t);
39         update(h[i]);
40     }
41     printf("%lld %lld",aa,at);
42     getchar(); getchar(); getchar();
43 }
View Code

 

posted @ 2015-10-11 18:32 Lenicodes 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值