poj 2352 Stars 數星星 詳解

2022-06-04 05:27:05 字數 1226 閱讀 6890

題目:

poj 2352 stars 數星星

題意:已知n個星星的座標。每個星星都有乙個等級,數值等於座標系內縱座標和橫座標皆不大於它的星星的個數。星星的座標按照縱座標從小到大的順序給出,縱座標相同時則按照橫座標從小到大輸出。 (0 <= x, y <= 32000) 要求輸出等級0到n-1之間各等級的星星個數。

分析:這道題不難想到n平方的演算法,即從縱座標最小的開始搜,每次找它前面橫座標的值比它小的點的個數,兩個for迴圈搞定,但是會超時。

所以需要用一些資料結構去優化,主要是優化找 橫座標比它小的點的個數 這裡可以用線段樹維護。我設sumv的意義是,從l到r(l,r代表橫座標的值)範圍內的橫座標的個數。它的左兒子是l到m內的個數,右兒子是m+1到r內的個數。葉節點當l=r是,就是橫座標為l的點的個數。最後用vis陣列記錄每個等級的數量即可。

我一開始的做法是先輸入完,然後直接構造所有節點的線段樹,但是這樣就不能同時判斷縱座標的大小,除錯了好久,發現是錯誤的。

由於題目是按照縱座標的大小,從小到大,同時橫座標從小到大給出的,因此,在一邊輸入的時候乙個點乙個點構造線段樹就 不用 判斷縱座標的大小。所以只要維護乙個橫座標的線段樹,在輸入的時候一邊輸,一邊查詢,一邊更新,這樣就可以了。在更新的時候,插入資料的方法是從根節點往下一點點更新,查詢的方法就是普通的線段樹查詢。但還有乙個小問題:在輸入的時候你不能知道線段樹的大小是多少,因為你不知道在整個資料中最大的那個橫座標。那我們只好慷慨一點,範圍直接用maxn(32000),雖然處理小資料時浪費了點空間,但其實沒事的。

查詢和更新的時間複雜度都是logn。總算法的時間複雜度o(nlogn)。

附上**:

1 #include2 #include3

using

namespace

std;

4const

int maxn=40010;5

6int x[maxn],y[maxn],n,sumv[maxn*4];7

intvis[maxn];

8intp;9

void update(int o,int l,int

r)1019}

2021

intans;

22void query(int o,int l,int

r)2332}

3334

intmain()

3545

for(int i=0;i<=n-1;i++) cout46return0;

47 }

poj 2352 stars 數狀陣列

題意 給出n個星星以座標形式 x,y 順序為先按y排序,再按x排序。求出每個等級的星星個數。星星的等級是按照其左下方的星星個數表示的,包括正左和正下的 因為星星座標是按照y的公升序給出的所以我們只要考慮x便可以,把x放進數狀陣列裡。includeconst int maxn 32005 int c ...

樹狀陣列 poj2352 Stars

stars 題目 題意 在乙個二維陣列中統計某個等級星星的個數,星星的等級為不比此星星高且不在它右邊範圍內的星星個數。題解 因為輸入的資料已經排序,只要一邊接收輸入一邊計算等級即可。include includeusing namespace std int a 15005 c 32010 defi...

poj 2352 Stars(樹狀陣列)

題意 依次給出n個星星的座標 y座標以非遞減的順序輸入 對於每個星星,她的等級等於她左下方的星星的個數和 包括邊界上的星星 要求輸出等級0到等級n 1的星星的個數。0 x,y,32000,1 n 15000 設x i 表示橫座標為i的星星有多少顆,那麼對於乙個單一詢問 星星 k,y 的等級是多少?要...