題目描述:
n個點m條邊的無向圖,詢問保留圖中編號在[l,r]的邊的時候圖中的聯通塊個數。
輸入格式:
第一行四個整數n、m、k、type,代表點數、邊數、詢問數以及詢問是否加密。 接下來m行,代表圖中的每條邊。 接下來k行,每行兩個整數l、r代表一組詢問。對於type=0的測試點,讀入的l和r即為詢問的l、r;對於type=1的測試點,每組詢問的l、r應為l xor lastans和r xor lastans。
輸出格式:
k行每行乙個整數代表該組詢問的聯通塊個數。
題解:
連通問題首先考慮lct。
考慮連通塊個數的計算方法。
連通塊個數=點數-去掉重邊後的邊數。
逐個列舉邊,如果這條邊連線的兩個點沒有連通,連線這條邊;反之,把兩點間最早的邊彈出,連線這條邊,並記錄彈出邊的編號。
每次查詢區間時,如果這條邊彈出的邊在區間內,那麼這條邊是無效的。
所以問題轉化為求區間內小於某個數的數的個數,可以主席樹維護。
時間複雜度$o(nlog_n)$
code:
1 #include2 #include3view codeusing
namespace
std;
4const
int n=400010;5
const
int inf=1e9+10;6
intn,m,k,ty,cnt,top;
7int a[n<<1],st[n<<1],ch[n<<1][2],f[n<<1],rev[n<<1],mi[n<<1];8
intu[n],v[n],rt[n],b[n],an[n];
9struct
segt[n<<5
];12
intread()
1320
return
s;21}22
intget(int
x)23
26bool isroot(int
x)27
30void pushup(int
x)31
36void pushdown(int
x)3744}
45void rotate(int
x)46
52 f[x]=z;f[y]=x;f[ch[x][k^1]]=y;
53 ch[y][k]=ch[x][k^1];ch[x][k^1]=y;
54pushup(y);pushup(x);55}
56void splay(int
x)57
67rotate(x);68}
69}70void access(int
x)7175}
76void makeroot(int
x)77
81void split(int x,int
y)82
86void link(int x,int
y)87
91void cut(int x,int
y)92
96int find(int
x)97
104splay(x);
105return
x;106
}107
void insert(int lk,int &rk,int l,int r,int
x)108
117else
121}
122int que(int lk,int rk,int l,int r,int l,int
r)123
130int
main()
131144 link(u[i],i+n);
145 link(i+n,v[i]);
146 insert(rt[i-1],rt[i],0
,m,b[i]);
147}
148else rt[i]=rt[i-1
];149
}150
for(int i=1;i<=k;i++)
155 an[i]=n-que(rt[l-1],rt[r],0,m,0,l-1
);156
}157
for(int i=1;i<=k;i++) printf("
%d\n
",an[i]);
158return0;
159 }
刷題 GERALD07加強版
是lct了。首先我們不知道聯通塊怎麼數。然後頹標籤知道了是lct。那麼考慮一下怎麼lct搞。有乙個很普遍的思路大家也應該都知道,就是如何求乙個區間中某種顏色的個數。這個可以很簡單的用主席樹來實現對吧,只需要記錄下來這種顏色上次出現的位置就可以了,然後在 l,r 中查詢值在 0,l 1 中的數的個數。...
題解 烷基計數 加強版 加強版
題目傳送門 問樹大小為 n 每個節點的兒子個數 le 3 的本質不同樹的個數。不考慮兒子之間的順序。n le10 5 因為這個題跟多項式關係比較大,所以就沒有放到 polya 定理學習筆記裡面。我們可以看出,假設我們設 f x 表示答案的普通型生成函式,那麼,我們就有 f x x frac 1 個人...
方格取數加強版 題解
因為乙個點的貢獻只能算一次,把點拆成2個點即可,連一條流量為 1 費用為這個點的值,然後再連一條流量為 infty 費用為 0 的邊,接下來對於每個點向它下方和它右方的點連一條流量為 infty 費用為 0 的邊即可。算最大費用,邊權取反。include int n,k,s,t,mincost in...