UVALive

给定一个图,支持三种操作:

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
",++kase,ans/cnt);
107     }
108     return 0;
109 }
View Code

线段树版:

 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
",++kase,ans/cnt);
88     }
89     return 0;
90 }
View Code
原文地址:https://www.cnblogs.com/asdfsag/p/10319592.html