POJ 2481 Cows(線段樹單點更新)

2021-06-29 09:28:52 字數 1498 閱讀 6906

兩個區間:[si, ei] 和 [sj, ej] (0 <= s < e <= 10^5)

若 si <= sj,且 ej <= ei 且 ei - si > ej - sj, 則第i個區間覆蓋第j個區間,即牛i比牛j強壯。問對於每一頭牛i有多少頭牛比它強壯。

這題先一看,不知如何下手。首先,將每個區間的s和e當做是(s,e)乙個點,這樣子把所有點在座標系上畫出來,你就會發現乙個很神奇的現象,題目要求就會變成:問每乙個點的左上角有多少個點?

那麼這題轉化為了,每個點的左上角有多少個點。但是點不是有序排好的,要預處理一下就可以。

如果正常做,那個y是遞增的,所以sum和update那個方向就會相反了,這個其實沒什麼所謂,一樣的,排序的時候先y由大到小排,y相同時x由小到大排,這樣小小的處理,就變成stars那題了!

首先將e[i]降序排序如果相等,則按s[i]的公升序排序。那麼執行完這部操作之後前面的

e[i]肯定 >= 後面的e[i],現在只要考慮s[i]就好了,每次計算s[i]之前有多少個點。

統計完之後將s[i]的位置加1,並更新線段樹。

這題需要離散化,如果兩頭牛的區間相同,則當前牛比它大的個數等於前面牛比它大的個數。

ac**

#include 

#include

#include

#define ls o*2

#define rs o*2+1

using

namespace

std;

const

int n = 1e5 + 10;

struct cow cow[n];

int sumv[n << 2], ans[n];

bool cmp(cow a, cow b)

int ql, qr;

int query(int o, int l, int r)

int p, v;

void modify(int o, int l, int r)

int m = (l + r)/2;

if(p <= m) modify(ls, l, m);

else modify(rs, m+1, r);

sumv[o] = sumv[ls] + sumv[rs];

}int main()

sort(cow+1, cow+1+n, cmp);

memset(sumv, 0, sizeof(sumv));

for(int i = 1; i <= n; i++) else

p = cow[i].s, v = 1;

modify(1, 1, n);

}printf("%d", ans[1]);

for(int i = 2; i <= n; i++) puts("");

}return

0;}

POJ 2481 Cows 線段樹 樹狀陣列

給出n個區間 輸出每個區間 是多少個區間的真子集 思路 區間左端點為第一關鍵字,右端點第二關鍵字,前者公升序後者降序 這樣對每個區間i,只需要查詢 ri到n有多少個右端點就是答案,可能有好幾個區間相同,那麼預處理一下最後減掉完全相同的區間即可 include include include incl...

poj 2481 Cows 樹狀陣列or線段樹

題意 給n個區間,問第i個區間是多少個區間的子區間。分析 可以吧每乙個線段看成是乙個點,這樣的話就等價於問乙個點的左上方有多少個點?這樣就和stars那題一樣了。因為是求左上方有多少個點,那麼把所有點按照y從大到小排列,這樣就可以按照順序求出0 x之間有多少個點,就是它左上方的點了。需要重點的處理。...

poj 2481 Cows 樹狀陣列or線段樹

題意 給n個區間,問第i個區間是多少個區間的子區間。分析 可以吧每乙個線段看成是乙個點,這樣的話就等價於問乙個點的左上方有多少個點?這樣就和stars那題一樣了。因為是求左上方有多少個點,那麼把所有點按照y從大到小排列,這樣就可以按照順序求出0 x之間有多少個點,就是它左上方的點了。需要重點的處理。...