jzoj4382-[GDOI2016模拟3.11]历史【并查集】
生活随笔
收集整理的這篇文章主要介紹了
jzoj4382-[GDOI2016模拟3.11]历史【并查集】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
有若干個事件
解題思路
使用并查集判斷是否聯通,并且不使用路徑壓縮。
用timxtim_xtimx?表示由faxfa_xfax?到xxx這跳邊是何時建立的,那我們詢問時若詢問的時間點time>timxtime>tim_xtime>timx?就不繼續往后跳即可。
但是這要會TLETLETLE,所以我們按秩合并,由小的合并到大的上。
這要因為每個的最多被合并lognlog\ nlog?n次所以時間復雜度為:O(nlogn):O(n\ log\ n):O(n?log?n)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=300100; int n,m,fa[N],tim[N],siz[N],c,angry,cnt; int find(int x,int t) {if(fa[x]==x||tim[x]>t) return x;return find(fa[x],t); } int main() {freopen("data.out","w",stdout);scanf("%d%d",&n,&m);for(int i=0;i<n;i++)fa[i]=i,siz[i]=1;while(m--){char op[3];int x,y,t;scanf("%s",op);if(op[0]=='K')angry=0,scanf("%d",&c);if(op[0]=='R'){scanf("%d%d",&x,&y);++cnt;if(angry) x=(x+c)%n,y=(y+c)%n;x=find(x,cnt);y=find(y,cnt);if(x==y) continue;if(siz[x]<siz[y])fa[x]=y,tim[x]=cnt,siz[y]+=siz[x];elsefa[y]=x,tim[y]=cnt,siz[x]+=siz[y];}if(op[0]=='T'){scanf("%d%d%d",&x,&y,&t);if(find(x,cnt)==find(y,cnt)&&find(x,cnt-t)!=find(y,cnt-t))angry=0,printf("Y\n");else angry=1,printf("N\n");}} }總結
以上是生活随笔為你收集整理的jzoj4382-[GDOI2016模拟3.11]历史【并查集】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P5007-DDOSvoid的疑惑【树形
- 下一篇: P4597-序列sequence【堆】