題目鏈接:http://poj.org/problem?id=2481 我感覺這道題給那個那個差的比較就是坑爹的……我按著差寫了大半天結果WA了個各種慘啊…… 好吧,這道題是按照權值建立線段樹,意思就是把每一個點加入到它應有的大小范圍內,線段樹上面每一個點維護的是該區間內有多少個點,這樣很容易就能查出來比某一個元素大的元素有多少個。而且,還得先對所有的點排序,主排序應該是把s從小到大排序,當s相等的時候,e從大到小排序,這樣就必須記錄每個元素原來的位置,這樣每次插入一個新的元素的時候,在它之前插入的所有的元素s上都是滿足條件的,換言之,線段樹中只需要維護e的情況就行了。其實……e符合條件了差值自然也就符合條件了。
 view code 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 #define lson l, m, rt << 1 7 #define rson m + 1, r, rt << 1 | 1 8 const int maxn = 100100; 9 struct data{ 10 int s, e, i; 11 friend bool operator < (const data &a, const data &b){ 12 if (a.s != b.s) return a.s < b.s; 13 return a.e > b.e; 14 } 15 }cow[maxn]; 16 int num[maxn << 2], ans[maxn]; 17 void build(int l, int r, int rt){ 18 num[rt] = 0; 19 if (l == r) return; 20 int m = (l + r) >> 1; 21 build(lson); 22 build(rson); 23 } 24 void update(int x, int l, int r, int rt){ 25 num[rt] += 1; 26 if (l == r) return; 27 int m = (l + r) >> 1; 28 if (x <= m) update(x, lson); 29 else update(x, rson); 30 } 31 int query(int ll, int rr, int l, int r, int rt){ 32 if (ll <= l && rr >= r) return num[rt]; 33 int m = (l + r) >> 1; 34 int ret = 0; 35 if (ll <= m) ret += query(ll, rr, lson); 36 if (rr > m) ret += query(ll, rr, rson); 37 return ret; 38 } 39 int main(){ 40 int n; 41 while (~scanf("%d", &n) && n){ 42 memset(ans, 0, sizeof(ans)); 43 int m = 0; 44 for (int i = 0; i < n; i++){ 45 scanf("%d%d", &cow[i].s, &cow[i].e); 46 cow[i].s += 1; cow[i].e += 1; 47 m = max(cow[i].e, m); 48 cow[i].i = i; 49 } 50 sort(cow, cow + n); 51 build (1, m, 1); 52 for (int i = 0; i < n; i++){ 53 if (i && cow[i].s == cow[i - 1].s && cow[i].e == cow[i - 1].e){ 54 ans[cow[i].i] = ans[cow[i - 1].i]; 55 update(cow[i].e, 1, m, 1); 56 } 57 else{ 58 ans[cow[i].i] = query(cow[i].e, m, 1, m, 1); 59 update(cow[i].e, 1, m, 1); 60 } 61 } 62 for (int i = 0; i < n; i++){ 63 printf("%d", ans[i]); 64 if (i != n-1) printf(" "); 65 else printf("\n"); 66 } 67 } 68 return 0; 69
|