zoukankan      html  css  js  c++  java
  • 【CH4201】楼兰图腾

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

    我们读入数据之后,分析问题,本题求解两个问题:‘^’的数量和‘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
  • 相关阅读:
    iOS- 移动端Socket UDP协议广播机制的实现
    iOS- 三步快速集成社交化分享工具ShareSDK
    iOS- iOS 7 的后台多任务 (Multitasking) 对比之前的异同、具体机制、变化
    iOS- Exception异常处理
    17. Subsets【medium】
    zookeeper程序员指南
    error while loading shared libraries错误解决
    82. Single Number【easy】
    53. Reverse Words in a String【easy】
    查看linux内核和版本信息
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10920718.html
Copyright © 2011-2022 走看看