POJ 2481 Cows

题意:有n头,他们都有两个属性。第i头牛的属性为s[i]和e[i] (s[i] < e[i]),定义它比第j头牛强壮即是s[i] <= s[j] && e[i] >= e[j] && e[i]-s[i] != e[j]-s[j]。对每投牛求比它强壮的牛有多少头。

  n <= 10^5, s[i],e[i] <= 10^5

解法:首先,对牛排序,按e[i]从大到小,e[i]相同则s[i]从小到大。则扫描到某头牛i的时候,比它强壮的牛都在它的前面(因为s[i]==s[j]&&e[i]==e[j]不算比它强壮)而且一定有它前面的牛e值大等于e[i],所以,只需要求s[i]小等于它的有多少个(如果牛i与牛i-1属性相同,则所求数量也相同,不用再计算)。

   考虑到s[i] <= 10^5,所以直接用num[10^5]记录即可,然后求前缀和。由于求前缀和的同时,也需要动态的修改,所以用树状数组。

Ps:感觉这道题也可以用二分来做,只不过在做专题,所以还是用树状数组做了。

tag:BIT

  1 /*
  2  * Author:  Plumrain
  3  * Created Time:  2014-02-16 21:05
  4  * File Name: BIT-POJ-2481.cpp
  5  */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <string>
 10 #include <cmath>
 11 #include <algorithm>
 12 #include <vector>
 13 #include <cstdlib>
 14 #include <sstream>
 15 #include <fstream>
 16 #include <list>
 17 #include <deque>
 18 #include <queue>
 19 #include <stack>
 20 #include <map>
 21 #include <set>
 22 #include <bitset>
 23 #include <cctype>
 24 #include <ctime>
 25 #include <utility>
 26 
 27 using namespace std;
 28 
 29 #define clr(x) memset(x, 0, sizeof(x))
 30 #define clrs(x,y) memset(x, y, sizeof(x))
 31 #define pb push_back
 32 #define sz(v) ((int)(v).size())
 33 #define all(t) t.begin(),t.end()
 34 #define INF 999999999999999999
 35 #define zero(x) (((x)>0?(x):-(x))<eps)
 36 #define out(x) cout<<#x<<":"<<(x)<<endl
 37 #define tst(a) cout<<a<<" "
 38 #define tst1(a) cout<<#a<<endl
 39 #define lowbit(x) ((x)&(-x))
 40 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 41 
 42 const double eps = 1e-8;
 43 const double PI = atan(1.0)*4;
 44 const int inf = 2147483647 / 2;
 45 
 46 typedef long long int64;
 47 typedef vector<int> vi;
 48 typedef vector<string> vs;
 49 typedef vector<double> vd;
 50 typedef pair<int, int> pii;
 51 
 52 inline int Mymod (int a, int b) {int x=a%b; if(x<0) x+=b; return x;}
 53 
 54 struct nod{
 55     int s, e, idx;
 56 };
 57 
 58 nod an[100005];
 59 int num[100005], c[100005], lim;
 60 vector<pii > ans;
 61 
 62 int sum(int x)
 63 {
 64     int ret = 0;
 65     while (x > 0)
 66         ret += c[x], x -= lowbit(x);
 67     return ret;
 68 }
 69 
 70 void add(int x, int d)
 71 {
 72     while (x <= lim)
 73         c[x] += d, x += lowbit(x);
 74 }
 75 
 76 bool cmp1(nod a, nod b)
 77 {
 78     return a.e > b.e || (a.e == b.e && a.s < b.s);
 79 }
 80 
 81 bool cmp2(pii a, pii b)
 82 {
 83     return a.second < b.second;
 84 }
 85 
 86 int main()
 87 {
 88 //    freopen("a.in","r",stdin);
 89 //    freopen("a.out","w",stdout);
 90 //    std::ios::sync_with_stdio(false);
 91     int n;
 92     while (scanf ("%d", &n) != EOF && n){
 93         for (int i = 0; i < n; ++ i){
 94             scanf ("%d%d", &an[i].s, &an[i].e);
 95             ++ an[i].s; ++ an[i].e;
 96             an[i].idx = i;
 97             lim = max(lim, an[i].s);
 98         }
 99         sort (an, an + n, cmp1);
100 
101         //for (int i = 0; i < n; ++ i) tst (an[i].s), tst (an[i].e), out (an[i].idx);
102 //
103         clr (num); clr (c);
104         ans.clear();
105         int cnt = 0;
106         for (int i = 0; i < n; ++ i){
107             if (!i || an[i].s != an[i-1].s || an[i].e != an[i-1].e)
108                 cnt = sum(an[i].s);
109                 
110             ans.pb (make_pair(cnt, an[i].idx));
111             add (an[i].s, 1);
112         }
113         sort (all(ans), cmp2);
114         
115         for (int i = 0; i < sz(ans); ++ i){
116             if (i) printf (" ");
117             printf ("%d", ans[i].first);
118         }
119         printf ("
");
120     }
121     return 0;
122 }
View Code
原文地址:https://www.cnblogs.com/plumrain/p/poj_2481.html