J Red-Black Paths(ICPC网络赛第一场)
J Red-Black Paths(ICPC網絡賽第一場)
題意:
有n個點,m次操作,有三種操作:
1 u v:從u向v建一個有向邊
2 u:將點u染成紅色
3 u: 將點u染成黑色
4 查詢最新生成的紅黑邊的異或值
紅黑邊的值為:∑1<=i<=length(path)ni?i\sum_{1<=i<=length(path)}n_{i}*i∑1<=i<=length(path)?ni??i
題解:
題解參考:
goto_1600
黑夜和白天
因為題目要求的是紅黑路徑的異或值,那么如果一個點不在紅黑路徑,那這個點就沒啥用,所以我們重新構圖,將一些無關緊要的點去掉
題目保證了∑紅黑路<=5000000\sum紅黑路<=5000000∑紅黑路<=5000000,所以處理后我們就可以跑
因為操作很多,我們可以考慮離線操作,對于每個操作都有時間戳,對于一個紅黑路,我們記錄其路徑上最后一次修改的時間戳tim,并在用數組ans[tim]來記錄這個路徑的異或值
因為每次詢問的是新增紅黑路的異或值
我們在ans上記錄的每個紅黑路徑最后一次修改的時間所對應的異或值
就比如下面這個數據,第5個位置是28,也就是在第5時刻,一個紅黑路最終形成且該路徑的異或值為28,很顯然,如果我們所詢問的時間戳tim如果在[5,7]之間,答案都是28,我們該如何實現快速查詢呢?
我們將ans從前往后異或一遍,ans[i]^=ans[i-1],此時ans[i]相當于第i時刻所有路徑的異或值,此時的異或值相當于是上一次路徑和本次路徑的異或,那么本次異或值就是和上次詢問的異或(再異或相當于消除)。你可以理解成兩個圖所有路徑的xor值,相同的被xor沒了,剩下的就是新增的紅黑路
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(); }總結
以上是生活随笔為你收集整理的J Red-Black Paths(ICPC网络赛第一场)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GCD HDU - 1695
- 下一篇: The 2019 ICPC Asia S