zoukankan      html  css  js  c++  java
  • 树状数组 之 poj 2481

    /*
    虽然事先知道这题可用树状数组求解,
    但对之前 poj 2352 理解不够深刻啊。。。在被提示可以考虑排序下,才想出办法了。。。
    其实和 poj 2352 解法一样,只不过不是那么明显了。
    先对 e 进行从大到小排序,
    如果 e 相等,对 s 进行从小到大排序。
    (对于排序后的Cows,假设 以前的Cows stronger 当前Cow,则必然 当前Cows的s 大于 以前的Cows的s)=>可用树状数组进行维护
    但 Wa 了几次次,原因: 
    若node[i].s == node[i-1].s, node[i].e == node[i-1].e 时,
    则:
    (1)两个的 stronger_num 相等,因为不满足 stronger 要求
    (题目要求:If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj. )
    (2)但仍需对树状数组进行更新 (否则,之后的 Cows 的 stronger_num 会少算)
    */
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int MAX_E = 100005;
    
    struct node { int s, e, pos; };
    node Arr[MAX_E];
    int n, stronger_num[MAX_E], bit[MAX_E];
    
    bool Cmp(const node &n1, const node &n2) {
    	if (n1.e == n2.e) return n1.s < n2.s;
    	else return n1.e > n2.e;
    }
    
    int mySum(int i)
    {
    	int s = 0;
    	while (i) {
    		s += bit[i];
    		i -= (i & (-i));
    	}
    	return s;
    }
    
    void myAdd(int i)
    {
    	while (i <= MAX_E) {
    		bit[i] += 1;
    		i += (i & (-i));
    	}
    }
    
    void Solve()
    {
    	for (int i = 1; i <= n; i++) {
    		if ((i - 1) > 0 && (Arr[i].s == Arr[i - 1].s) && (Arr[i].e == Arr[i - 1].e)) {
    			stronger_num[Arr[i].pos] = stronger_num[Arr[i - 1].pos];
    			myAdd(Arr[i].s);
    			continue;
    		}
    		stronger_num[Arr[i].pos] = mySum(Arr[i].s);
    		myAdd(Arr[i].s);
    	}
    	for (int i = 1; i <= n; i++) {
    		if (i != 1) printf(" ");
    		printf("%d", stronger_num[i]);
    	}
    	printf("
    ");
    }
    
    int main()
    {
    	//freopen("input.txt", "r", stdin);
    	while (scanf("%d", &n) && n)
    	{
    		memset(stronger_num, 0, sizeof(stronger_num));
    		memset(bit, 0, sizeof(stronger_num));
    		int t_s, t_e;
    		for (int i = 1; i <= n; i++)
    		{
    			scanf("%d %d", &t_s, &t_e);
    			Arr[i].s = t_s + 1;
    			Arr[i].e = t_e + 1;
    			Arr[i].pos = i;
    		}
    		sort(Arr + 1, Arr + (n + 1), Cmp);
    		Solve();
    	}
    }
    
  • 相关阅读:
    回文链表
    istringstream
    编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个对立的元素存于vector中
    c++ primer,友元函数上的一个例子(By Sybase)
    类的静态成员
    聚合类和字面值常量类
    隐式的类类型转换
    构造函数
    类的作用域
    类的其他特性
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140849.html
Copyright © 2011-2022 走看看