• 【BZOJ2422】Times 树状数组


    【BZOJ2422】Times

    Description

    小y作为一名资深的dotaer,对视野的控制有着深刻的研究。每个单位在一段特定的时间内会出现在小y的视野内,除此之外的时间都在小y看不到的地方。在小y看来,视野内的单位数量越多,他就越安全,因为这意味着有可能藏在阴影中的单位就越少。现在,小y已经知道了每个单位会在什么时候出现在视野内,他想知道,在一段时间内,总共有多少个单位出现在他的视野内过。

    Input

    第一行有两个整数n,m,表示一共有n个单位,而小y有m个问题。
    接下来n行,每行两个数a,b,表示这个单位a秒时出现在小y的视野内,出现了b秒。
    接下来m行,每行两个整数x,y,表示从x秒开始,经过y秒,其中有多少个单位出现过。

    Output

    m行,即对于小y提出的每个问题的答案。

    Sample Input

    3 2
    2 5
    0 10
    5 8
    0 6
    8 2

    Sample Output

    3
    2

    【数据范围】
    1<=n,m<=200000
    1<=x,y,a,b<=maxlongint

    题解:这题的思路还是比较好的。

    正着做比较难,考虑反着做。我们可以统计在那段时间内它没有看到过多少个单位,则要么b<x<y要么x<y<a,并且这两种情况不会重复计算,用树状数组统计一下就好了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=200010;
    int n,m,nm,tot;
    int x[maxn],y[maxn],l[maxn],r[maxn];
    struct BIT
    {
    	int s[maxn<<2];
    	inline void updata(int x)
    	{
    		for(int i=x;i<=nm;i+=i&-i)	s[i]++;
    	}
    	inline int query(int x)
    	{
    		int i,ret=0;
    		for(i=x;i;i-=i&-i)	ret+=s[i];
    		return ret;
    	}
    }s1,s2;
    struct node
    {
    	int org,k;
    	ll val;
    }p[maxn<<2];
    bool cmp(const node &a,const node &b)
    {
    	return a.val<b.val;
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i;
    	for(i=1;i<=n;i++) p[++tot].val=rd(),p[tot+1].val=p[tot].val+rd()-1,p[tot].org=p[tot+1].org=i,p[++tot].k=1;
    	for(i=1;i<=m;i++) p[++tot].val=rd(),p[tot+1].val=p[tot].val+rd()-1,p[tot].org=p[tot+1].org=i,p[tot].k=2,p[++tot].k=3;
    	sort(p+1,p+tot+1,cmp);
    	p[0].val=-1;
    	for(i=1;i<=tot;i++)
    	{
    		if(p[i].val>p[i-1].val)	nm++;
    		switch(p[i].k)
    		{
    			case 0:x[p[i].org]=nm;	break;
    			case 1:y[p[i].org]=nm;	break;
    			case 2:l[p[i].org]=nm;	break;
    			case 3:r[p[i].org]=nm;	break;
    		}
    	}
    	for(i=1;i<=n;i++)	s1.updata(y[i]),s2.updata(x[i]);
    	for(i=1;i<=m;i++)	printf("%d
    ",n-(s1.query(l[i]-1)+s2.query(nm)-s2.query(r[i])));
    	return 0;
    }

     

  • 相关阅读:
    Python3 学习第八弹: 模块学习一之模块变量
    Python3 学习第六弹: 迭代器与生成器
    Python3 学习第五弹:类与面向对象
    Java之泛型
    Java之工具类Collections
    Java之map
    Java集合之List
    Java集合之TreeSet
    Java集合
    Java异常处理
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7535676.html
Copyright © 2020-2023  润新知