zoukankan      html  css  js  c++  java
  • hdu 5792(树状数组,容斥) World is Exploding

    hdu 5792

    要找的无非就是一个上升的仅有两个的序列和一个下降的仅有两个的序列,按照容斥的思想,肯定就是所有的上升的乘以所有的下降的,然后再减去重复的情况。

    先用树状数组求出lx[i](在第 i 个数左边的数中比它小的数的个数),ld[i](在第 i 个数左边的数中比它大的数的个数),rx[i](在第 i 个数右边的数中比它小的数的个数)

    ,rd[i](在第 i 个数右边的数中比它大的数的个数)。然后重复的情况无非就是题目中a与c重合(rx[i]*rd[i]),a与d重合(rd[i]*ld[i]),b与c重合(lx[i]*rx[i]),b与

    d重合(lx[i]*ld[i])

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 const int M = 5e4 + 100;
    10 int a[M],b[M],bit[M],has[M];
    11 ll ld[M],lx[M],rd[M],rx[M];
    12 
    13 int lowbit(int x){return x&-x;}
    14 
    15 int sum(int x){
    16    int ret=0;
    17    while (x>0)
    18        ret+=bit[x],x-=lowbit(x);
    19    return ret;
    20 }
    21 
    22 void add(int x,int d){
    23    while (x<=M)
    24       bit[x]+=d,x+=lowbit(x);
    25 }
    26 
    27 int main()
    28 {
    29     int n;
    30     while (~scanf("%d",&n)){
    31         for (int i=1 ; i<=n ; i++) scanf("%d",&a[i]),b[i]=a[i];
    32         sort(b+1,b+n+1);
    33         int m=unique(b+1,b+n+1)-b;
    34         //cout<<m<<endl;
    35         m--;
    36         for (int i=1 ; i<=n ; i++){
    37             a[i]=lower_bound(b+1,b+m+1,a[i])-b;
    38         }
    39         memset(lx,0,sizeof(lx));
    40         memset(ld,0,sizeof(ld));
    41         memset(rd,0,sizeof(rd));
    42         memset(rx,0,sizeof(rx));
    43         memset(bit,0,sizeof(bit));
    44         memset(has,0,sizeof(has));
    45         ll ans=0,ans1=0,ans2=0;
    46         //cout<<"xx"<<endl;
    47         for (int i=1 ; i<=n ; i++){
    48             has[a[i]]++;
    49             lx[i]=sum(a[i]-1);
    50             ld[i]=(i-has[a[i]])-lx[i];
    51             add(a[i],1);
    52         }
    53         memset(bit,0,sizeof(bit));
    54         memset(has,0,sizeof(has));
    55         for (int i=n ; i>=1 ; i--){
    56             has[a[i]]++;
    57             rx[i]=sum(a[i]-1);
    58             rd[i]=(n-i+1-has[a[i]])-rx[i];
    59             add(a[i],1);
    60             ans1+=rx[i];
    61             ans2+=rd[i];
    62         }
    63         ans=ans1*ans2;
    64         for (int i=1 ; i<=n ; i++){
    65             ans-=rd[i]*ld[i];
    66             ans-=rx[i]*lx[i];
    67             ans-=rd[i]*rx[i];
    68             ans-=ld[i]*lx[i];
    69         }
    70         printf("%I64d
    ",ans);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    SQL Server将一列的多行内容拼接成一行的问题讨论
    SQL 获取 IDENTITY 三种方法 SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的区别
    构建高性能服务(二)
    乐观锁解决高并发
    c#问答篇:对象与引用变量-----初学者的困惑
    vs调试 本地IIS
    【转】android adb常用指令
    【转】使用 JMeter 完成常用的压力测试
    【转】利用 Apache JMeter 测试 WebSphere 性能
    【转】用JMeter来测试Tomcat的性能
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5737947.html
Copyright © 2011-2022 走看看