zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    JS 实现点击<a> 标签的时候给其换背景
    LeetCode解题思路 (一)
    读书笔记之《操作系统概念》
    读书笔记之《程序员代码面试指南(字符串问题)》
    读书笔记之《程序员代码面试指南(栈和队列)》
    读书笔记之《程序员代码面试指南(数组和矩阵问题)》
    读书笔记之《程序员代码面试指南(位运算及大数据)》
    项目常用功能代码
    读书笔记之《深入理解Java虚拟机》
    读书笔记之《程序员代码面试指南(链表问题)》
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10319592.html
Copyright © 2011-2022 走看看