J Red-Black Paths(ICPC网络赛第一场)
J Red-Black Paths(ICPC網(wǎng)絡(luò)賽第一場(chǎng))
題意:
有n個(gè)點(diǎn),m次操作,有三種操作:
1 u v:從u向v建一個(gè)有向邊
2 u:將點(diǎn)u染成紅色
3 u: 將點(diǎn)u染成黑色
4 查詢(xún)最新生成的紅黑邊的異或值
紅黑邊的值為:∑1<=i<=length(path)ni?i\sum_{1<=i<=length(path)}n_{i}*i∑1<=i<=length(path)?ni??i
題解:
題解參考:
goto_1600
黑夜和白天
因?yàn)轭}目要求的是紅黑路徑的異或值,那么如果一個(gè)點(diǎn)不在紅黑路徑,那這個(gè)點(diǎn)就沒(méi)啥用,所以我們重新構(gòu)圖,將一些無(wú)關(guān)緊要的點(diǎn)去掉
題目保證了∑紅黑路<=5000000\sum紅黑路<=5000000∑紅黑路<=5000000,所以處理后我們就可以跑
因?yàn)椴僮骱芏?#xff0c;我們可以考慮離線(xiàn)操作,對(duì)于每個(gè)操作都有時(shí)間戳,對(duì)于一個(gè)紅黑路,我們記錄其路徑上最后一次修改的時(shí)間戳tim,并在用數(shù)組ans[tim]來(lái)記錄這個(gè)路徑的異或值
因?yàn)槊看卧?xún)問(wèn)的是新增紅黑路的異或值
我們?cè)赼ns上記錄的每個(gè)紅黑路徑最后一次修改的時(shí)間所對(duì)應(yīng)的異或值
就比如下面這個(gè)數(shù)據(jù),第5個(gè)位置是28,也就是在第5時(shí)刻,一個(gè)紅黑路最終形成且該路徑的異或值為28,很顯然,如果我們所詢(xún)問(wèn)的時(shí)間戳tim如果在[5,7]之間,答案都是28,我們?cè)撊绾螌?shí)現(xiàn)快速查詢(xún)呢?
我們將ans從前往后異或一遍,ans[i]^=ans[i-1],此時(shí)ans[i]相當(dāng)于第i時(shí)刻所有路徑的異或值,此時(shí)的異或值相當(dāng)于是上一次路徑和本次路徑的異或,那么本次異或值就是和上次詢(xún)問(wèn)的異或(再異或相當(dāng)于消除)。你可以理解成兩個(gè)圖所有路徑的xor值,相同的被xor沒(méi)了,剩下的就是新增的紅黑路
0 0 0 0 28 28 28 15 15 15 24 7 7代碼:
#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn=5e6+9; vector<int>Q; vector<int>R; int black[maxn]; int red[maxn]; struct edge{int u,v,tim; }; vector<edge>e; vector<PII>vec[maxn]; int vis[maxn]; int tag[maxn]; ll ans[maxn]; void dfs(int u){vis[u]=1;if(black[u])tag[u]=1;for(auto it:vec[u]){int v=it.first;int w=it.second;if(vis[v]){tag[u]|=tag[v];continue;}dfs(v);tag[u]|=tag[v];} } void rebuild(){for(int i=0;i<=5000000;i++)vec[i].clear();for(auto it:e){if(tag[it.u]&tag[it.v]){vec[it.u].push_back({it.v,it.tim});}} } void path(int u,int maxx,ll sum,int dep){if(black[u]){int tim=max(maxx,black[u]);ans[tim]^=sum;}for(auto it:vec[u]){int v=it.first;int tim=it.second;path(v,max(maxx,tim),sum+1ll*dep*v,dep+1);}} int main() {rd_test();int n;read(n);for(int i=1;i<=n;i++){int op,u,v;read(op);if(op==1){read(u,v);vec[u].push_back({v,i});e.push_back({u,v,i});}else if(op==2){int u;cin>>u;R.push_back(u);red[u]=i;}else if(op==3){cin>>u;black[u]=i;}else if(op==4){Q.push_back(i);}}for(auto v:R){if(!vis[v])dfs(v); }rebuild();for(auto v:R){path(v,red[v],1ll*v,2);}for(int i=1;i<=n;i++)ans[i]^=ans[i-1];ll res=0;for(int i=0;i<Q.size();i++){res=ans[Q[i]];if(i) res^=ans[Q[i-1]];cout<<res<<endl;}return 0;//Time_test(); }總結(jié)
以上是生活随笔為你收集整理的J Red-Black Paths(ICPC网络赛第一场)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: GCD HDU - 1695
- 下一篇: qq域名邮箱怎么注册(qq域名邮箱怎么注