zoukankan      html  css  js  c++  java
  • UVA1479 Graph and Queries

    思路

    恶心人的题目
    还是类似永无乡一题的Treap启发式合并思路
    但是由于加边变成了删边
    所以应该离线后倒序处理
    数组要开够

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    int Nodecnt=0,root[250000*2],fa[250000*2],w_p[250000*2],cnt,n,m;
    struct Edge{
        int u,v;
    }E[250000*2];
    struct oper{
        int opt,x,k,v;
    }Ask[250000*2];
    struct Node{
        int lson,rson,sz,val,ran;
    }Treap[250000*2];
    set<int> use;
    stack<int> ans;
    int find(int x){
        if(fa[x]==x)
            return x;
        else
            return fa[x]=find(fa[x]);
    }
    queue<int> q;
    void throwin(int x){
        q.push(x);
    }
    int getnew(int val){
        int o;
        if(q.size())
            o=q.front(),q.pop();
        else
            o=++Nodecnt;
        Treap[o].lson=Treap[o].rson=0;
        Treap[o].sz=1;
        Treap[o].ran=rand();
        Treap[o].val=val;
        return o;
    }
    void pushup(int o){
        Treap[o].sz=Treap[Treap[o].lson].sz+Treap[Treap[o].rson].sz+1;
    }
    void rorateL(int &o){
        int x=Treap[o].rson;
        Treap[o].rson=Treap[x].lson;
        Treap[x].lson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void rorateR(int &o){
        int x=Treap[o].lson;
        Treap[o].lson=Treap[x].rson;
        Treap[x].rson=o;
        pushup(o);
        pushup(x);
        o=x;
    }
    void insert(int val,int &o){
        if(!o){
            o=getnew(val);
            return;
        }
        Treap[o].sz++;
        if(val<=Treap[o].val){
            insert(val,Treap[o].lson);
            if(Treap[Treap[o].lson].ran<Treap[o].ran)
                rorateR(o);
        }
        else{
            insert(val,Treap[o].rson);
            if(Treap[Treap[o].rson].ran<Treap[o].ran)
                rorateL(o);
        }
    }
    void del(int val,int &o){
        if(o==0)
            return;
        if(Treap[o].val==val){
            if(Treap[o].lson*Treap[o].rson==0){
                throwin(o);
                o=Treap[o].lson+Treap[o].rson;
                return;
            }
            else{
                if(Treap[Treap[o].lson].ran<Treap[Treap[o].rson].ran){
                    rorateR(o);
                    Treap[o].sz--;
                    del(val,Treap[o].rson);
                    return;
                }
                else{
                    rorateL(o);
                    Treap[o].sz--;
                    del(val,Treap[o].lson);
                    return;
                }
            }
        }
        else if(val<Treap[o].val){
            Treap[o].sz--;
            del(val,Treap[o].lson);
            return;
        }
        else{
            Treap[o].sz--;
            del(val,Treap[o].rson);
            return;
        }
    }
    int query(int val,int o){
        if(!o)
            return 0;
        if(val==Treap[Treap[o].rson].sz+1)
            return Treap[o].val;
        else if(val>Treap[Treap[o].rson].sz+1)
            return query(val-Treap[Treap[o].rson].sz-1,Treap[o].lson);
        else
            return query(val,Treap[o].rson);
    }
    void dfs(int &o,int to){
        if(!o)
            return;
        insert(Treap[o].val,root[to]);
        dfs(Treap[o].lson,to);
        dfs(Treap[o].rson,to);
        throwin(o);
        o=0;
    }
    void init(void){
        Nodecnt=0;
        cnt=0;
        memset(Treap,0,sizeof(Treap));
        memset(root,0,sizeof(root));
        memset(fa,0,sizeof(fa));
        memset(w_p,0,sizeof(w_p));
        memset(E,0,sizeof(E));
        memset(Ask,0,sizeof(Ask));
        while(!q.empty())
            q.pop();
        use.clear();
    }
    int main(){
        freopen("test.in","r",stdin);
        freopen("test.out","w",stdout);
        int inq=0;
        while(scanf("%d %d",&n,&m)==2){
            inq++;
            if(n==0&&m==0)
                break;
            init();
            for(int i=1;i<=n;i++){
                scanf("%d",&w_p[i]);
                fa[i]=i;
            }  
            for(int i=1;i<=m;i++)
                scanf("%d %d",&E[i].u,&E[i].v),use.insert(i);
            char opt=getchar();
            while(opt!='E'&&opt!='Q'&&opt!='C'&&opt!='D')
                opt=getchar();
            while(opt!='E'){
                ++cnt;
                if(opt=='D'){
                    Ask[cnt].opt=1;
                    scanf("%d",&Ask[cnt].x);
                    use.erase(Ask[cnt].x);
                }
                else if(opt=='Q'){
                    Ask[cnt].opt=2;
                    scanf("%d %d",&Ask[cnt].x,&Ask[cnt].k);
                }
                else if(opt=='C'){
                    Ask[cnt].opt=3;
                    scanf("%d %d",&Ask[cnt].x,&Ask[cnt].v);
                    int t=w_p[Ask[cnt].x];
                    w_p[Ask[cnt].x]=Ask[cnt].v;
                    Ask[cnt].v=t;
                }
                opt=getchar();
                while(opt!='E'&&opt!='Q'&&opt!='C'&&opt!='D')
                    opt=getchar();
            }
            for(int i=1;i<=n;i++)
                insert(w_p[i],root[i]);
            for(auto it = use.begin();it!=use.end();it++){
                int a=E[(*it)].u,b=E[(*it)].v;
                if(find(a)!=find(b)){
                    if(Treap[root[find(a)]].sz<Treap[root[find(b)]].sz){
                        dfs(root[find(a)],find(b));
                        fa[find(a)]=find(b);
                    }
                    else{
                        dfs(root[find(b)],find(a));
                        fa[find(b)]=find(a);
                    }
                }
            }
            for(int i=cnt;i>=1;i--){
                if(Ask[i].opt==1){
                    int a=E[Ask[i].x].u,b=E[Ask[i].x].v;
                    if(find(a)!=find(b)){
                        if(Treap[root[find(a)]].sz<Treap[root[find(b)]].sz){
                            dfs(root[find(a)],find(b));
                            fa[find(a)]=find(b);
                        }
                        else{
                            dfs(root[find(b)],find(a));
                            fa[find(b)]=find(a);
                        }
                    } 
                }
                else if(Ask[i].opt==2){
                    ans.push(query(Ask[i].k,root[find(Ask[i].x)]));
                }
                else{
                    del(w_p[Ask[i].x],root[find(Ask[i].x)]);
                    w_p[Ask[i].x]=Ask[i].v;
                    insert(w_p[Ask[i].x],root[find(Ask[i].x)]);
                }
            }
            double mid=0.0;
            int qqq=0;
            while(!ans.empty()){
                qqq++;
                // printf("%d
    ",ans.top());
                mid+=ans.top();
                ans.pop();
            }
            printf("Case %d: %.6lf
    ",inq,mid/qqq);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS动画(一)coreAnimation 教程(转)
    sdwebimage基本用法及原理
    iOS推送
    Objective-C中的Block
    loadView、viewDidLoad、initWithCoder、initWithNibName、awakeFromNib的调用时间及用法
    提纲挈领-我的博客内容架构(持续更新)
    读过的书籍及思考系列 (详细列表)-持续更新
    看过的影视及思考系列(详细列表)-持续更新
    自学笔记系列:《Python学习手册 第五版》 -写在开始之前
    《Python网络爬虫权威指南 第二版》 -第1章 软件及BeautifulSoup库准备
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10711519.html
Copyright © 2011-2022 走看看