
题意
给出一张无向图,定义S[x]表示与点x直接相连的点集,有两个操作
1 x y表示将第x到第y条边状态变化(若存在则删除,不存在则建立)
2 x y询问S[x]与S[y]是否相等
题解
有一个技巧可以压缩的表示点集:给每个点随机一个key,S[x]就可以表示为
与x相连的点的key亦或起来。
考虑如何维护S[x], 因为修改操作是对输入的顺序的区间修改,我们就按边输入的
顺序进行分块,用sum[i][j]记录第i块对点j的贡献值,也就是如果第i块有一条边u-v
那么$sum[i][u] \bigoplus= key[v], sum[i][v] \bigoplus= key[u]$
查询一个点的点集就变成求$sum[1][x] \bigoplus sum[2][x] \bigoplus sum[3][x] \cdots \bigoplus sum[num][x]$
修改的时候如果修改区间落在不同的块上,对夹在中间的块打个lazy标记,表示查询的时候
不用亦或上这个块的贡献,对与两边块内的修改操作可以再用一个数组S记录暴力修改的状态,
比如要修改区间$[l,r]$是块内的,那么就修改$S[u[i]] \bigoplus= key[v[i]], S[v[i]] \bigoplus= key[u[i]] (i\in[l,r])$
查询x的点集时再xor上S[x]就行,总的来说就是块间修改只需要对sum打标记,块内修改就
暴力更改S,最后复杂度$O(q\sqrt m)$,分块的时候块数要开成$1.5\sqrt m$
代码
1 |
|