UOJ_407_【IOI2018】狼人
阿新 • • 發佈:2018-11-25
分析:
- 分別建立最小/最大kruskal重構樹。
- 每次詢問給出的兩個點能走到的部分分別對應兩棵樹\(dfs\)序的一段區間。
- 轉化成判斷矩形中是否有點。
程式碼:
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> #include "werewolf.h" using namespace std; #define M 400050 #define vi vector<int> int n,m,q_times,fa[M],ln; int dfn[2][M],enp[2][M],Ls[2][M],Rs[2][M],dfc,w[2][M]; int f[2][20][M],idf[2][M],root[M],ls[M*22],rs[M*22],siz[M*22],cnt; char buf[100000],*p1,*p2; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() { int x=0; char s=nc(); while(s<'0') s=nc(); while(s>='0') x=(((x<<2)+x)<<1)+s-'0',s=nc(); return x; } struct A { int a,b,c; bool operator < (const A &u) const { return c>u.c; } }e[M]; int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);} void df1(int x,int o) { dfn[o][x]=++dfc; idf[o][dfc]=x; if(Ls[o][x]) df1(Ls[o][x],o); if(Rs[o][x]) df1(Rs[o][x],o); enp[o][x]=dfc; } void update(int l,int r,int x,int &p,int q) { p=++cnt; siz[p]=siz[q]+1; ls[p]=ls[q]; rs[p]=rs[q]; if(l==r) return ; int mid=(l+r)>>1; if(x<=mid) update(l,mid,x,ls[p],ls[q]); else update(mid+1,r,x,rs[p],rs[q]); } int query(int l,int r,int x,int y,int p,int q) { if(x<=l&&y>=r) return siz[p]-siz[q]; int mid=(l+r)>>1,re=0; if(x<=mid) re+=query(l,mid,x,y,ls[p],ls[q]); if(y>mid) re+=query(mid+1,r,x,y,rs[p],rs[q]); return re; } vi check_validity(int n,vi EX,vi EY,vi QX,vi QY,vi QL,vi QR) { ln=n*2-1; m=EX.size(); int i,tot=n; for(i=1;i<=m;i++) { e[i].a=EX[i-1]; e[i].b=EY[i-1]; e[i].a++; e[i].b++; e[i].c=min(e[i].a,e[i].b); } sort(e+1,e+m+1); for(i=1;i<=ln;i++) fa[i]=i; for(i=1;i<=m;i++) { int dx=find(e[i].a),dy=find(e[i].b); if(dx!=dy) { fa[dx]=fa[dy]=++tot; Ls[0][tot]=dx; Rs[0][tot]=dy; w[0][tot]=e[i].c; f[0][0][dx]=f[0][0][dy]=tot; } } df1(tot,0); dfc=0; for(i=1;i<=ln;i++) fa[i]=i; tot=n; for(i=1;i<=m;i++) e[i].c=max(e[i].a,e[i].b); sort(e+1,e+m+1); for(i=m;i;i--) { int dx=find(e[i].a),dy=find(e[i].b); if(dx!=dy) { fa[dx]=fa[dy]=++tot; Ls[1][tot]=dx; Rs[1][tot]=dy; w[1][tot]=e[i].c; f[1][0][dx]=f[1][0][dy]=tot; } } df1(tot,1); int j,k; for(i=0;i<2;i++) { for(j=1;(1<<j)<=ln;j++) { for(k=1;k<=ln;k++) { f[i][j][k]=f[i][j-1][f[i][j-1][k]]; } } } for(i=1;i<=dfc;i++) { root[i]=root[i-1]; int x=idf[1][i]; if(x<=n) { update(1,dfc,dfn[0][x],root[i],root[i]); } } vi ans; int x,y,l,r; q_times=QX.size(); for(j=0;j<q_times;j++) { x=QX[j]; y=QY[j]; l=QL[j]; r=QR[j]; x++;y++;l++;r++; for(i=19;i>=0;i--) { if(f[0][i][x]&&w[0][f[0][i][x]]>=l) x=f[0][i][x]; if(f[1][i][y]&&w[1][f[1][i][y]]<=r) y=f[1][i][y]; } int t=query(1,dfc,dfn[0][x],enp[0][x],root[enp[1][y]],root[dfn[1][y]-1]); ans.push_back(t>0); } return ans; }