UVALive - 5031 Graph and Queries (并查集+平衡树/线段树)
给定一个图,支持三种操作:
1.删除一条边
2.查询与x结点相连的第k大的结点
3.修改x结点的权值
解法:离线倒序操作,平衡树or线段树维护连通块中的所有结点信息,加个合并操作就行了。
感觉线段树要好写很多。
平衡树(Treap)版:
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int N=5e5+10; 5 struct E { 6 int u,v; 7 } e[N]; 8 int a[N],faz[N],n,m,del[N]; 9 int father(int x) {return ~faz[x]?faz[x]=father(faz[x]):x;} 10 11 struct Treap { 12 static const int N=1e6+10; 13 int rnd() {static int seed=time(0)%0x7fffffff; return seed=seed*48271ll%0x7fffffff;} 14 int ch[N][2],siz[N],val[N],fa[N],tot,rd[N],rt[N]; 15 void init() {tot=ch[0][0]=ch[0][1]=siz[0]=val[0]=rd[0]=0;} 16 int newnode(int x) { 17 int u=++tot; 18 ch[u][0]=ch[u][1]=0; 19 siz[u]=1,val[u]=x,rd[u]=rnd(); 20 return u; 21 } 22 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;} 23 void rot(int& u,int f) { 24 int v=ch[u][f]; 25 ch[u][f]=ch[v][f^1],ch[v][f^1]=u; 26 pu(u),pu(v),u=v; 27 } 28 void ins(int& u,int x) { 29 if(!u) {u=newnode(x); return;} 30 int f=x>=val[u]; 31 ins(ch[u][f],x); 32 if(rd[ch[u][f]]>rd[u])rot(u,f); 33 if(u)pu(u); 34 } 35 void del(int& u,int x) { 36 if(val[u]==x) { 37 if(!ch[u][0])u=ch[u][1]; 38 else if(!ch[u][1])u=ch[u][0]; 39 else { 40 int f=rd[ch[u][1]]>rd[ch[u][0]]; 41 rot(u,f),del(ch[u][f^1],x); 42 } 43 } else del(ch[u][x>=val[u]],x); 44 if(u)pu(u); 45 } 46 int kth(int u,int k) { 47 if(!u)return 0; 48 int t=siz[ch[u][0]]+1; 49 if(k==t)return val[u]; 50 return k<t?kth(ch[u][0],k):kth(ch[u][1],k-t); 51 } 52 void merge(int& u,int& v) { 53 if(!u)return; 54 ins(v,val[u]); 55 merge(ch[u][0],v),merge(ch[u][1],v); 56 } 57 } treap; 58 59 struct Q { 60 int f,u,k; 61 } qr[N]; 62 int nqr; 63 64 void mg(int x,int y) { 65 int fx=father(x),fy=father(y); 66 if(fx==fy)return; 67 if(treap.siz[treap.rt[fx]]>treap.siz[treap.rt[fy]])swap(fx,fy); 68 treap.merge(treap.rt[fx],treap.rt[fy]); 69 faz[fx]=fy; 70 } 71 72 int main() { 73 int kase=0; 74 while(scanf("%d%d",&n,&m)&&n) { 75 treap.init(); 76 nqr=0; 77 memset(faz,-1,sizeof faz); 78 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 79 for(int i=1; i<=m; ++i)scanf("%d%d",&e[i].u,&e[i].v); 80 char ch; 81 while(scanf(" %c",&ch)&&ch!='E') { 82 if(ch=='Q')scanf("%d%d",&qr[nqr].u,&qr[nqr].k),qr[nqr++].f=1; 83 else if(ch=='D')scanf("%d",&qr[nqr].u),qr[nqr++].f=0; 84 else if(ch=='C')scanf("%d%d",&qr[nqr].u,&qr[nqr].k),swap(a[qr[nqr].u],qr[nqr].k),qr[nqr++].f=2; 85 } 86 for(int i=1; i<=n; ++i)treap.rt[i]=treap.newnode(a[i]); 87 memset(del,0,sizeof del); 88 for(int i=0; i<nqr; ++i)if(qr[i].f==0)del[qr[i].u]=1; 89 for(int i=1; i<=m; ++i)if(!del[i])mg(e[i].u,e[i].v); 90 reverse(qr,qr+nqr); 91 double ans=0; 92 int cnt=0; 93 for(int i=0; i<nqr; ++i) { 94 if(qr[i].f==1) { 95 int u=qr[i].u,r=treap.rt[father(u)],k=qr[i].k; 96 ans+=treap.kth(r,treap.siz[r]-k+1),cnt++; 97 } else if(qr[i].f==0)mg(e[qr[i].u].u,e[qr[i].u].v); 98 else { 99 int u=qr[i].u,k=qr[i].k; 100 int fu=father(u); 101 treap.del(treap.rt[fu],a[u]); 102 treap.ins(treap.rt[fu],k); 103 a[u]=k; 104 } 105 } 106 printf("Case %d: %f\n",++kase,ans/cnt); 107 } 108 return 0; 109 }
线段树版:
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int N=5e5+10; 5 struct E { 6 int u,v; 7 } e[N]; 8 int a[N],faz[N],n,m,del[N]; 9 int father(int x) {return ~faz[x]?faz[x]=father(faz[x]):x;} 10 11 struct Segtree { 12 static const int N=4e6+10; 13 int ls[N],rs[N],siz[N],tot,rt[N]; 14 void init() {tot=ls[0]=rs[0]=siz[0]=0;} 15 int newnode() {int u=++tot; ls[u]=rs[u]=siz[u]=0; return u;} 16 void pu(int u) {siz[u]=siz[ls[u]]+siz[rs[u]];} 17 void add(int& u,int x,int f,int l=-1000000,int r=1000000) { 18 if(!u)u=newnode(); 19 siz[u]+=f; 20 if(l==r)return; 21 int mid=(l+r)>>1; 22 x<=mid?add(ls[u],x,f,l,mid):add(rs[u],x,f,mid+1,r); 23 } 24 void merge(int& u,int v,int l=-1000000,int r=1000000) { 25 if(!v)return; 26 if(!u) {u=v; return;} 27 if(l==r) {siz[u]+=siz[v]; return;} 28 int mid=(l+r)>>1; 29 merge(ls[u],ls[v],l,mid); 30 merge(rs[u],rs[v],mid+1,r); 31 pu(u); 32 } 33 int kth(int u,int k,int l=-1000000,int r=1000000) { 34 if(l==r)return l; 35 int mid=(l+r)>>1; 36 return k<=siz[ls[u]]?kth(ls[u],k,l,mid):kth(rs[u],k-siz[ls[u]],mid+1,r); 37 } 38 } segtree; 39 40 struct Q { 41 int f,u,k; 42 } qr[N]; 43 int nqr; 44 45 void mg(int x,int y) { 46 int fx=father(x),fy=father(y); 47 if(fx==fy)return; 48 segtree.merge(segtree.rt[fy],segtree.rt[fx]); 49 faz[fx]=fy; 50 } 51 52 int main() { 53 int kase=0; 54 while(scanf("%d%d",&n,&m)&&n) { 55 segtree.init(); 56 nqr=0; 57 memset(faz,-1,sizeof faz); 58 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 59 for(int i=1; i<=m; ++i)scanf("%d%d",&e[i].u,&e[i].v); 60 char ch; 61 while(scanf(" %c",&ch)&&ch!='E') { 62 if(ch=='Q')scanf("%d%d",&qr[nqr].u,&qr[nqr].k),qr[nqr++].f=1; 63 else if(ch=='D')scanf("%d",&qr[nqr].u),qr[nqr++].f=0; 64 else if(ch=='C')scanf("%d%d",&qr[nqr].u,&qr[nqr].k),swap(a[qr[nqr].u],qr[nqr].k),qr[nqr++].f=2; 65 } 66 for(int i=1; i<=n; ++i)segtree.rt[i]=segtree.newnode(),segtree.add(segtree.rt[i],a[i],1); 67 memset(del,0,sizeof del); 68 for(int i=0; i<nqr; ++i)if(qr[i].f==0)del[qr[i].u]=1; 69 for(int i=1; i<=m; ++i)if(!del[i])mg(e[i].u,e[i].v); 70 reverse(qr,qr+nqr); 71 double ans=0; 72 int cnt=0; 73 for(int i=0; i<nqr; ++i) { 74 if(qr[i].f==1) { 75 int u=qr[i].u,r=segtree.rt[father(u)],k=qr[i].k; 76 if(k>0&&k<=segtree.siz[r])ans+=segtree.kth(r,segtree.siz[r]-k+1); 77 cnt++; 78 } else if(qr[i].f==0)mg(e[qr[i].u].u,e[qr[i].u].v); 79 else { 80 int u=qr[i].u,k=qr[i].k; 81 int fu=father(u); 82 segtree.add(segtree.rt[fu],a[u],-1); 83 segtree.add(segtree.rt[fu],k,1); 84 a[u]=k; 85 } 86 } 87 printf("Case %d: %f\n",++kase,ans/cnt); 88 } 89 return 0; 90 }