P4246 SHOI2008 堵塞的交通

2022-10-09 06:48:07 字數 1666 閱讀 4950

題意簡述

維護乙個 \(2*n\) 的網格圖的動態連通性

思路既然是動態連通性,那麼我們直接離線線段樹分治+可撤銷並查集

上面的做法太暴力了,我們考慮分析一些性質

注意到聯通的資訊是可以合併的,可以考慮使用線段樹維護

乙個想法是維護區間 左上/左下 到 右上/右下 的連通性

但這樣忽略了一種情況:

(1,1) - (1,2)   (1,3) - (1,4)

| |

(2,1) - (2,2) - (2,3) - (2,4)

也就是說,我們可以通過詢問區間 左邊/右邊 部分實現行的改變

那麼再維護兩個資訊 \(l,r\) 表示區間 左上左下 , 右上右下 的連通性

合併區間和查詢時列舉中間點即可

#include #include using namespace std;

const int maxn = 1e5;

int n , v[ maxn + 5 ] , r[ 2 ][ maxn + 5 ];

struct node ;

struct segment_tree ;

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

for( int j = 0 ; j <= 1 ; j ++ )

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

s.chk[ i ][ j ] |= p.chk[ i ][ k ] & r[ k ][ md ] & q.chk[ k ][ j ];

s.l = p.l | ( p.chk[ 0 ][ 0 ] && p.chk[ 1 ][ 1 ] && r[ 0 ][ md ] & r[ 1 ][ md ] & q.l );

s.r = q.r | ( q.chk[ 0 ][ 0 ] && q.chk[ 1 ][ 1 ] && r[ 0 ][ md ] & r[ 1 ][ md ] & p.r );

return s;

}void build( int x , int l = 1 , int r = n )

build( ls , l , mid ); build( rs , mid + 1 , r );

}void update( int x , int pos , int l = 1 , int r = n )

update( ls , pos , l , mid ); update( rs , pos , mid + 1 , r );

tr[ x ] = merge( tr[ ls ] , tr[ rs ] , mid );

}node query( int x , int ql , int qr , int l = 1 , int r = n )

}tr;

char s[ 10 ];

int main( )

else v[ c1 ] = 1;

tr.update( 1 , c1 );

}if( s[ 0 ] == 'c' )

else v[ c1 ] = 0;

tr.update( 1 , c1 );

}if( s[ 0 ] == 'a' )

}return 0;

}

SHOI2008 堵塞的交通

有一篇超級棒的線段樹 大力分類討論的題解!戳我 可是我還是不會寫這個做法qwqwqwq 這裡提供線段樹分治的寫法。感覺比較不需要智商,就是跑的有點慢了。include include include include include include include include define max...

SHOI2008 堵塞的交通

這裡提供幾種不用腦子的演算法 當然是離線的 text 記下每條邊的刪除時間,用 text 維護最大生成樹,每次加進一條邊時,跟原來那條鏈上的做比較,刪除那條刪除時間最短的邊即可。線段樹分治 這個演算法將每條邊的加入和刪除時間加入到線段樹中,所以在遍歷到葉子節點時,那個時刻存在的邊都已經在並查集上了,...

SHOI2008 堵塞的交通

有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可 以被看成是乙個2行c列的矩形網格,網格上的每個點代表乙個城市,相鄰的城市之間有一條道路,所以總共有2c個 城市和3c 2條道路。小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不...