線段樹(先占個坑,有空去填)

2021-06-17 18:31:28 字數 2901 閱讀 4305

#include#include#include#define ll long long

#define lson l , m , rt << 1

#define rson m + 1 , r , rt << 1 | 1

using namespace std ;

const int maxn = 611111 ;

ll sum[15][maxn<<2] ;

int cnt[maxn<<2] , f[maxn<<1] , n , k ;

struct edge

} edge[maxn<<1] ;

void build(int l,int r,int rt)

void push_up(int l,int r,int rt)//將當前的值都清空,然後重新計算

}void update(int l,int r,int flag,int l,int r,int rt)

int m=(l+r)>>1;

if(l<=m)update(l,r,flag,lson);

if(r>m)update(l,r,flag,rson);

push_up(l,r,rt);

}int main ()

sort ( f + 1 , f + tot + 1 ) ;

sort ( edge + 1 , edge + tot + 1 ) ;

int t = unique ( f + 1 , f + tot + 1 ) - f - 1 ;

build ( 1 , t - 1 , 1 ) ;

for ( i = 1 ; i < tot ; i ++ )

printf ( "case %d: %lld\n" , ++ ca , ans ) ;

}}

1455 - kingdom

題意:有一些分散的城市,修建一些邊將這些城市連線起來,在同乙個連通塊的城市被稱為乙個州。有兩種操作,(1)修建一條road,將城市a,b連線起來。(2)詢問縱座標為c的一條水平線能穿過幾個州,穿過的這些州的城市總共和是多少。

解題思路:並差集+線段樹,並差集裡面儲存的是州的資訊,要記錄的有州的根節點,州的縱座標的最大值和最小值,以及這個州的size(也就是這個州包含了幾個城市,橫座標其實沒有用)。建兩棵線段樹,分別儲存[l,r]有多少個州,[l,r]有多少個城市,那麼詢問時就是單點詢問了(c告訴你是k*0.5的,你可以把所有的數都擴大兩倍,那麼就全都是整數了)。road操作時,找到這兩個城市所屬的集合,先看給你的兩個城市是否在同乙個集合,如果在同乙個集合,那就不進行任何操作。否則就根據這兩個集合縱座標的最值關係進行區間更新(這個要分類討論,城市的個數是不會少的,但州的個數有可能會減,仔細討論清楚)。然後將兩個城市歸併到同乙個集合。

#include#include#include#define lson l , m , rt << 1

#define rson m + 1 , r , rt << 1 | 1

using namespace std ;

const int maxn = 1000002 ;

int sum[2][maxn<<2] , add[2][maxn<<2] ;

struct fa f[maxn] ;

int find ( int a )

int p[maxn] ;

void push_down ( int rt , int flag )

}void update ( int a , int b , int flag , int c , int l , int r , int rt )

push_down ( rt , flag ) ;

int m = ( l + r ) >> 1 ;

if ( a <= m ) update ( a , b , flag , c , lson ) ;

if ( m < b ) update ( a , b , flag , c , rson ) ;

sum[flag][rt] = sum[flag][rt<<1|1] + sum[flag][rt<<1] ;

}int query ( int a , int flag , int l , int r , int rt )

char s[111] ;

int main ()

memset ( sum , 0 , sizeof ( sum ) ) ;

memset ( add , 0 , sizeof ( add ) ) ;

scanf ( "%d" , &m ) ;

while ( m -- )

else

else if ( d2 > u1 )

else if ( u2 >= d1 && u2 <= u1 )

else

f[y].u = max ( f[y].u , f[x].u ) ;

f[y].d = min ( f[y].d , f[x].d ) ;

f[x].fa = y ;

f[y].size += f[x].size ;

// printf ( "%d %d\n" , query ( 9 , 1 , 0 , maxn - 111 , 1 ) , query ( 9 , 0 , 0 , maxn - 111 , 1 ) ) ;

}} }

return 0 ;}/*

3 10

1 7

5 7

8 6

3 5

5 5

2 3

10 3

7 2

4 1

11 1

11 road 0 1

road 3 5

road 4 2

road 3 8

line 4.5

*/

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...