日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

A-Graph Games_2019牛客暑期多校训练营(第三场)

發(fā)布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 A-Graph Games_2019牛客暑期多校训练营(第三场) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意

給出一張無向圖,定義S[x]表示與點x直接相連的點集,有兩個操作
1 x y表示將第x到第y條邊狀態(tài)變化(若存在則刪除,不存在則建立)
2 x y詢問S[x]與S[y]是否相等

題解

有一個技巧可以壓縮的表示點集:給每個點隨機一個key,S[x]就可以表示為
與x相連的點的key亦或起來。
考慮如何維護(hù)S[x], 因為修改操作是對輸入的順序的區(qū)間修改,我們就按邊輸入的
順序進(jìn)行分塊,用sum[i][j]記錄第i塊對點j的貢獻(xiàn)值,也就是如果第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]\)
修改的時候如果修改區(qū)間落在不同的塊上,對夾在中間的塊打個lazy標(biāo)記,表示查詢的時候
不用亦或上這個塊的貢獻(xiàn),對與兩邊塊內(nèi)的修改操作可以再用一個數(shù)組S記錄暴力修改的狀態(tài),
比如要修改區(qū)間\([l,r]\)是塊內(nèi)的,那么就修改\(S[u[i]] \bigoplus= key[v[i]], S[v[i]] \bigoplus= key[u[i]] (i\in[l,r])\)
查詢x的點集時再xor上S[x]就行,總的來說就是塊間修改只需要對sum打標(biāo)記,塊內(nèi)修改就
暴力更改S,最后復(fù)雜度\(O(q\sqrt m)\),分塊的時候塊數(shù)要開成\(1.5\sqrt m\)

代碼

#include <bits/stdc++.h>using namespace std; const int mx = 2e5+10; typedef long long ll;int belong[mx], block, num, l[mx], r[mx], id[mx]; int n, m, q, u[mx], v[mx]; int lazy[mx]; ll sum[450][mx], S[mx];void build() {block = 1.5*sqrt(m);num = m / block;if (m % block) num++;for (int i = 1; i <= num; i++) {l[i] = (i-1) * block + 1;r[i] = i * block;lazy[i] = 1;for (int j = 1; j <= n; j++)sum[i][j] = 0;}r[num] = m;for (int i = 1; i <= m; i++)belong[i] = (i-1) / block + 1;for (int i = 1; i <= n; i++) S[i] = 0;}void update(int x, int y) {if (belong[x] == belong[y]) {for (int i = x; i <= y; i++) {S[u[i]] ^= id[v[i]];S[v[i]] ^= id[u[i]];}return;}int L = belong[x], R = belong[y];for (register int i = x; i <= r[L]; i++) {S[u[i]] ^= id[v[i]];S[v[i]] ^= id[u[i]];}for (register int i = L+1; i < R; i++) lazy[i] ^= 1;for (register int i = l[R]; i <= y; i++) {S[u[i]] ^= id[v[i]];S[v[i]] ^= id[u[i]];} }int main() {srand(time(NULL));for (int i = 1; i < 100005; i++) id[i] = rand() + 1;int T;scanf("%d", &T);while (T--) {scanf("%d%d", &n, &m);build();for (int i = 1; i <= m; i++) {scanf("%d%d", &u[i], &v[i]);sum[belong[i]][u[i]] ^= id[v[i]];sum[belong[i]][v[i]] ^= id[u[i]];}scanf("%d", &q);while (q--) {int op, x, y;scanf("%d%d%d", &op, &x, &y);if (op == 1) {update(x, y);} else {ll ansx = S[x], ansy = S[y];for (int i = 1; i <= num; i++) {if (lazy[i]) {ansx ^= sum[i][x];ansy ^= sum[i][y];}}putchar(ansx==ansy?'1':'0');}}putchar('\n');}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/bpdwn-cnblogs/p/11290523.html

總結(jié)

以上是生活随笔為你收集整理的A-Graph Games_2019牛客暑期多校训练营(第三场)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。