POJ 3067 Japan 二維樹狀陣列

2021-06-03 17:02:58 字數 1364 閱讀 5613

是乙個比較不錯的題目。

題目大意是,在一張地圖上,西邊從上到下均勻排了一列點,東邊也是這樣,然後給出若干個邊,都是從西邊的點連到東邊的點上。問最後這些邊的交點,所謂交點,就是兩個邊交叉得到的交點,如果交點在結點上,是不算數的。

首先思考一下基本做法,很容易想到,跟某條邊相交的邊數,跟其在東邊和西邊的編號有關係。然後就發現,如果某條邊在西邊的編號大於這條邊,並且東邊的編號小於這條邊,就會出現交叉,當然如果某條邊在西邊的編號小於這條邊,並且東邊的編號大於這條邊,也會出現交叉。但是,如果兩種都計算,顯然是會重複計算的,我們就取前一種來計算。

那麼就從西邊結點,從上到下,對每一條邊,觀察符合條件的邊,然後求和,但是題目給出的邊數可能高達一百萬。如果直接列舉顯然是不靠譜的。

這時,我們再轉換一下模型,想象一下以西邊頂點為x軸,東邊頂點為y軸,建立直角座標系,那麼問題就轉化成了,對於每個點,看其右下方點的個數,然後求和,

這時候就不難想到要用到樹狀陣列了。

樹狀陣列要用到二維的,對於每條邊呢,用座標插入時,第一維的x應該是遞減的,第二維的y是遞增的,表示插入這個座標後,比其x小,並且y大的在統計的時候都能統計到這個座標。然後求和的時候就是反過來了。

/*

id: sdj22251

prog: subset

lang: c++

*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define maxn 100007

#define inf 1000000000

#define eps 1e-7

using namespace std;

int a[1005][1005];

int xx[1000005], yy[1000005];

int n, m;

int lowbit(int x)

void modify(int x, int y)

long long get_sum(int x, int y)

int main()

long long ans = 0;

for(int i = 0; i < k; i++)

ans += get_sum(xx[i], yy[i]);

printf("test case %d: %i64d\n", ++cas, ans);

}return 0;

}

POJ 3067 Japan 二維樹狀陣列

是乙個比較不錯的題目。題目大意是,在一張地圖上,西邊從上到下均勻排了一列點,東邊也是這樣,然後給出若干個邊,都是從西邊的點連到東邊的點上。問最後這些邊的交點,所謂交點,就是兩個邊交叉得到的交點,如果交點在結點上,是不算數的。首先思考一下基本做法,很容易想到,跟某條邊相交的邊數,跟其在東邊和西邊的編號...

poj 3067 Japan 二維樹狀陣列(入門)

二維樹狀陣列 入門 二維樹狀陣列直接上就行了。用結構體line存完輸入資料後,按照x從小到大排序。遍歷一遍,每次加完crossing數後在更新維護二維樹狀陣列。這類題關鍵在如何用get sum 就是對 面積區間 按個人理解自己取的名 的正確選取 仔細考慮邊界情況,是否減一加一。本題 ans get ...

POJ 3067 Japan 線段樹 轉化

poj 3067 japan 線段樹 轉化 題意 有一幅圖,左邊m個結點,右邊n個結點,給出k條邊連線左邊結點和右邊結點 求這些邊相互交叉的個數,乙個點只會有兩條邊經過 思路 同樣將線段轉化成點然後放在二維平面圖上,對於兩條線段 si,ei sj,ej 滿足交叉的條件是siej si sj ei i...