zoukankan      html  css  js  c++  java
  • BZOJ4994: [Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

    Description

    给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数

    Input

     

    Output

     

    Sample Input

    4
    3
    2
    4
    4
    1
    3
    2
    1

    Sample Output

    3

    HINT

    N<=100000

    Solution

    套路题

    显然这种题可以排序掉第一次,然后用树状数组解第二次,但是比较麻烦,一时没有想出来,其实也可以的

    当时就再想了想,其实对于每个$i$,对于答案有贡献的显然就是它第一次出现之后,且还没有出现第二次的数,所以可以更方便的去维护

    第一次出现就把出现的位置保存下来顺便+1

    然后第二次出现就把这个数删掉,它不会对其他答案产生贡献了,这个数对其他数的贡献为$sum(i)-sum(last[x])$($last[x]$表示数$x$第一次出现的位置)

    所以就拿树状数组维护一下就好了

    #include <bits/stdc++.h> 
    
    using namespace std ;
    
    #define ll long long
    
    int n , c[ 200010 ];
    int last[ 100010 ] ;
    
    int lowbit( int x ) {
        return x & -x ;
    }
    
    void add( int x , int val ) {
        for( int i = x ; i <= 2 * n ; i += lowbit( i ) ) 
            c[ i ] += val ;
    }
    
    int query( int x ) {
        int ans = 0 ;
        for( int i = x ; i ; i -= lowbit( i ) ) ans += c[ i ] ;
        return ans ;
    }
    
    int main() {
        scanf( "%d" , &n ) ;
        ll ans = 0 ;
        for( int i = 1;  i <= 2*n ; i ++ ) {
            int x ;
            scanf( "%d" , &x ) ;
            if( !last[ x ] ) last[ x ] = i , add( i , 1 ) ;
            else {
                add( last[ x ] , -1 ) ;
                ans += 1ll * query( i ) - query( last[ x ] ) ;
            } 
        }
        printf( "%lld
    " , ans ) ;
        return 0 ;
    }
  • 相关阅读:
    关于Ajax中this失效
    添加时间周期一年半年季度
    回车事件
    alt与title
    关于checked="checked"却不显示选中的“对勾”
    正则表达式的使用
    关于JQ 查找不到对象的clientHeight,
    Mysql笔记之 -- 开启Mysql慢查询
    Mysql笔记之 -- 小试MYSQL主从配置
    Linux系统学习笔记之 1 一个简单的shell程序
  • 原文地址:https://www.cnblogs.com/henry-1202/p/BZOJ4994.html
Copyright © 2011-2022 走看看