题意:有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 }