• BZOJ4994 [Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ4994


    题意概括

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

      n<=100000(这个数据范围是我凑出来的,但是我没试过更小的范围,BZOJ上没写数据范围(截止2017-08-24))


    题解

      水题,开一个树状数组在线解决。

      比如我们顺着扫过去,当到达一个 bj 时,我们求满足条件的 ai,bi 个数,其实就是求 bi~bj 之间有几个数出现一次而且是第一次出现。

      所以我们开树状数组维护。

      我顺着做过去,对于每一个数字i,在ai的地方+1,到了bi就在ai的地方-1,并统计区间ans,累加即可。


    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N=100000+5;
    int n,c[N*2],f[N];
    LL ans=0;
    int lowbit(int x){
    	return x&-x;
    }
    void add(int x,int d){
    	for (;x<=n*2;x+=lowbit(x))
    		c[x]+=d;
    }
    int sum(int x){
    	int ans=0;
    	for (;x>0;x-=lowbit(x))
    		ans+=c[x];
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	memset(c,0,sizeof c);
    	memset(f,0,sizeof f);
    	for (int i=1,x;i<=n*2;i++){
    		scanf("%d",&x);
    		if (!f[x]){
    			f[x]=i;
    			add(i,1);
    		}
    		else {
    			ans+=sum(i-1)-sum(f[x]);
    			add(f[x],-1);
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    王者荣耀_KEY
    月亮之眼_KEY
    编号中的数学_KEY
    BZOJ1854_游戏_KEY
    BZOJ1059_矩阵游戏_KEY
    最小覆盖_KEY
    Dijkstra堆优化学习
    LuoguP1196_银河英雄传说_KEY
    BZOJ1207_打鼹鼠_KEY
    Codevs1380没有上司的舞会_KEY
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ4994.html
Copyright © 2020-2023  润新知