zoukankan      html  css  js  c++  java
  • POJ 2481:Cows 树状数组

    Cows
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 14906   Accepted: 4941

    Description

    Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. 

    Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John's N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E]. 

    But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj

    For each cow, how many cows are stronger than her? Farmer John needs your help!

    Input

    The input contains multiple test cases. 
    For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge. 

    The end of the input contains a single 0.

    Output

    For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi

    Sample Input

    3
    1 2
    0 3
    3 4
    0
    

    Sample Output

    1 0 0
    

    Hint

    Huge input and output,scanf and printf is recommended.

    题意是给出了一堆牛的能力值,这些能力值是用一定区间表示的。一头牛比另一头牛强壮就是这头牛的能力值区间真包含了另一头牛的能力值区间(能力值区间相等不能算作比其强壮)。问对于每一头牛来说,在这个群体中有多少头牛比自己强壮。

    之前做过树状数组的几道题,长时间不做,好多地方又都不熟了,或者说之前可能没有完全理解,这次也算是好好理解。这个题和之前POJ上问两条路相交的题目差不多,思想都是控制变量,用排序的方式将一个变量控制住,用剩下来的一个变量可以用树状数组来控制。

    首先因为要求的是所有牛中比自己强壮的有多少个。所以我希望每一个数据插入树状数组时,都能够得到比自己强壮的牛的数量。那就要求在数组中比自己靠前位置的,这时候发现树状数组能记录比自己靠前位置的,所以用树状数组记录的是s,而不是e。因为要比自己强壮嘛。

    s用树状数组搞定了,那所以这时候自然会想到,此时我希望插入树状数组时,前面的e都比我当前的e大,这样我插入的时候就完全不用担心e值是否被包含进去了,所以这时用sort来解决就好啦~

    这个题目,觉得排序的想法比树状数组都还要重要,或者说做树状数组的题,好多都是用树状数组控制一个变量,用其他方法(排序神马的)解决剩下的变量。

    代码:

    #include <iostream>  
    #include <algorithm>  
    #include <cmath>  
    #include <vector>  
    #include <string>  
    #include <cstring>  
    #pragma warning(disable:4996)  
    using namespace std;
    
    int n;
    int ans[100005];
    int cnt[100005];
    
    struct no
    {
    	int s,e;
    	int pos;
    }node[100005];
    
    bool cmp(no n1,no n2)
    {
    	if(n1.e == n2.e)
    	{
    		return n1.s<n2.s;
    	}
    	else
    	{
    		return n1.e>n2.e;
    	}
    }
    
    int lowbit(int x)
    {
    	return x&(-x);
    }
    
    void add(int x)
    {
    	while(x<=n)
    	{
    		ans[x]++;
    		x=x+lowbit(x);
    	}
    }
    
    int sum(int x)
    {
    	int res=0;
    	while(x>0)
    	{
    		res+=ans[x];
    		x=x-lowbit(x);
    	}
    	return res;
    }
    
    int main()
    {
    	int i;
    	while(scanf("%d",&n)!=EOF)
    	{
    		if(n==0)
    			break;
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d%d",&node[i].s,&node[i].e);
    			node[i].pos=i;
    		}
    		memset(ans,0,sizeof(ans));
    		memset(cnt,0,sizeof(cnt));
    		sort(node+1,node+n+1,cmp);
    		
    		for(i=1;i<=n;i++)
    		{
    			if(node[i].e == node[i-1].e && node[i].s == node[i-1].s)
    			{
    				cnt[node[i].pos] = cnt[node[i-1].pos];
    			}
    			else
    			{
    				cnt[node[i].pos] = sum(node[i].s+1);
    			}
    			add(node[i].s+1);
    		}
    		
    		for(i=1;i<=n;i++)
    		{
    			if(i==1)
    			{
    				printf("%d",cnt[1]);
    			}
    			else
    			{
    				printf(" %d",cnt[i]);
    			}
    		}
    		printf("
    ");
    	}
    	return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Masonry
    数据解析
    UIImage 两种初始化的区别
    GCD
    数据处理之文件读写
    关注即时通讯
    跳转appStore评分
    iOS 9 Safari广告拦截插件
    Cocoapods的安装以及使用
    iOS中Block的基础用法
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899553.html
Copyright © 2011-2022 走看看