給定n個點的座標,代表n各城市,有m種操作,共分兩種,一種是連線,把兩個點連起來(一旦構成連通圖,這個連通圖即為乙個州),還有種詢問操作,為y=c,(c為小數部分恒為.5的實數),問y=c這條線經過了多少個大周,這些州總共有多少個城市
很明顯要用到並查集,比較好的做法是把並查集落實到線段樹上,並查集維護的是每個集合的最大y和最小y,以及rank表示集合數目。但是線段樹要用到離散化、
然後參照乙個用樹狀陣列的部落格,其實思路差不多,都是把每次的變更落實到樹上
不過這個樹狀陣列跟之前寫的不一樣,這個是改段查點型的,之前的是改點查段型的,其實只要改一下輔助陣列的定義即可,在這個樹狀陣列裡面,把輔助陣列d當做從1到當前所有的變更,每次更新時從當前往遞減方向,所以,為了得到某個點值,必須把當前點以及當前之前的變更都加起來。
所以這個
add(int loc,int v)
while (loc>0)
query(int loc)
int ret=0;
while (locreturn ret;
因為給定的數是.5的實數,故意把座標往後壓一位即可,把每乙個小格仔往後壓成乙個點即可
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;67
intn,m;
8int f[100010],rank[100010],y1[100010],y2[100010];9
void
init()
1015}16
int findset(int
x)17
21return
f[x];22}
23int lowbit(int
x)24
27struct
bit28
35void add(int l,int r,int
v)40
while (l>=1)44
}45int query(int
x)46
52return
ret;53}
54}city,state;
55void unit(int r1,int
r2)56
60int
main()
6179 city.limit=state.limit=maxn;
80 scanf("
%d",&m);
81for (int i=1;i<=m;i++)
95else
96if (rank[r1]==1 || rank[r2]==1
)106
else
107120
}121
else
127}
128}
129return0;
130 }
LA 4730 Kingdom 線段樹 並查集
la 4730 題意 有n個帶座標的城市,和m個操作,每次操作 road a b,連線a,b城市成為乙個州 或者 line c,查詢y c的水平線和多少個州相交以及這些州一共包含多少個城市。思路 可以把每個城市的x座標忽略,把縱座標看做線段樹的區間,乙個點就相當於更新區間 y,y 一條線就相當於更新...
並查集 線段樹 LA 4730 Kingdom
題目傳送門 題意 訓練指南p248 分析 第乙個操作可以用並查集實現,儲存某集合的最小高度和最大高度以及城市個數。運用線段樹成端更新來統計乙個區間高度的個數,此時高度需要離散化。這題兩種資料結構一起使用,聯絡緊密。include using namespace std const int n 1e5...
LA3027之並查集
在處理一些有n個元素的合併於查詢問題時,我們經常會使用到並查集 union find set 這樣一種樹形資料結構來處理,一般來說這樣的問題都是看似很簡單,但是資料量很大,容易超時,但是採用並查集這種資料結構卻能很容易解決這些問題。一般來說,並查集使用陣列來實現,它實現的功能也很簡單,主要涉及兩個基...