zoukankan      html  css  js  c++  java
  • hdu3276 Graph and Queries 离线+treap

    之前用splay一直超时。。。这次改用treap过的也不轻松,调了一晚上。。。主要是移除操作,一个是该up的时候没up,另外一个是up的时候子结点可能不存在没判断RE了。。毕竟指针版。。。还有就是delete的时候把不该删的也删了。。。

    都是比较低级的细节错误。。。

    但是再让我写一遍这种题我觉得还是没问题的,这一晚上不是白浪费的。维护权值用treap果然比splay好写多了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=2000100;
    const int INF=1e9+10;
    
    int n,m;
    int val[maxn];
    struct Edge
    {
        int u,v;
        bool e;
        void read()
        {
            scanf("%d%d",&u,&v);
            e=1;
        }
    };Edge e[maxn];
    char op[20];int x,k;
    struct Query
    {
        char op;int x,k;
    };Query q[maxn];int qn;
    int fa[maxn];
    
    struct Node
    {
        Node *ch[2];
        int r,v;
        int sz;
        Node()
        {
            ch[0]=ch[1]=NULL;
            r=rand();v=0;
            sz=1;
        }
        void up()
        {
            sz=1;
            if(ch[0]!=NULL) sz+=ch[0]->sz;
            if(ch[1]!=NULL) sz+=ch[1]->sz;
        }
    };Node *rt[maxn];
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    
    void rot(Node* &o,int d)
    {
        Node* k=o->ch[d^1];
        o->ch[d^1]=k->ch[d];
        k->ch[d]=o;
        o->up();k->up();
        o=k;
    }
    
    void Insert(Node* &o,int x)
    {
        if(o==NULL){
            o=new Node();
            o->v=x;
            return;
        }
        int d=x<o->v?0:1;
        Insert(o->ch[d],x);
        if(o->ch[d]->r>o->r) rot(o,d^1);
        o->up();
    }
    
    void Remove(Node* &o,int x)
    {
        if(o==NULL) return;
        if(o->v==x){
            Node* k=o;
            if(o->ch[0]!=NULL&&o->ch[1]!=NULL){
                int d=o->ch[0]->r>o->ch[1]->r?0:1;
                rot(o,d^1);Remove(o->ch[d^1],x);
                o->up();
            }
            else{
                Node* k=o;
                if(o->ch[0]==NULL) o=o->ch[1];
                else o=o->ch[0];
                delete k;
            }
            return;
        }
        if(x<o->v) Remove(o->ch[0],x);
        else Remove(o->ch[1],x);
        o->up();
    }
    
    void JoinTo(Node* &x,Node* &y)
    {
        if(x==NULL) return;
        JoinTo(x->ch[0],y);
        JoinTo(x->ch[1],y);
        Insert(y,x->v);
        delete x;x=NULL;
    }
    
    int Kth(Node* &o,int k)
    {
        if(o==NULL) return 0;
        if(k<0||k>o->sz) return 0;
        int s=o->ch[1]==NULL?0:o->ch[1]->sz;
        if(k==s+1) return o->v;
        if(k<s+1) return Kth(o->ch[1],k);
        else return Kth(o->ch[0],k-(s+1));
    }
    
    void Free(Node* &o)
    {
        if(o==NULL) return;
        Free(o->ch[0]);
        Free(o->ch[1]);
        delete(o);
        o=NULL;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif
        int casen=1;
        while(cin>>n>>m,n||m){
            REP(i,1,n) rt[i]=NULL;
            REP(i,1,n) scanf("%d",&val[i]);
            REP(i,1,m) e[i].read();
            qn=0;
            while(scanf("%s",op)&&op[0]!='E'){
                if(op[0]=='D') scanf("%d",&x),e[x].e=0,q[++qn]={op[0],x,k};
                else{
                    scanf("%d%d",&x,&k);
                    if(op[0]=='Q') q[++qn]={op[0],x,k};
                    else{
                        q[++qn]={op[0],x,val[x]};
                        val[x]=k;
                    }
                }
            }
            REP(i,1,n) Insert(rt[i],val[i]);
            REP(i,1,n) fa[i]=i;
            ll ans=0,cnt=0;
            REP(i,1,m){
                if(e[i].e){
                    int x=find(e[i].u),y=find(e[i].v);
                    if(x!=y){
                        if(rt[x]->sz>rt[y]->sz) swap(x,y);
                        fa[x]=y,JoinTo(rt[x],rt[y]);
                    }
                }
            }
            for(int i=qn;i>=1;i--){
                int x=q[i].x,k=q[i].k;
                if(q[i].op=='D'){
                    int xt=find(e[x].u),yt=find(e[x].v);
                    if(xt!=yt){
                        if(rt[xt]->sz>rt[yt]->sz) swap(xt,yt);
                        fa[xt]=yt,JoinTo(rt[xt],rt[yt]);
                    }
                }
                else if(q[i].op=='C'){
                    int xt=find(x);
                    Remove(rt[xt],val[x]);
                    Insert(rt[xt],k);
                    val[x]=k;
                }
                else{
                    int xt=find(x);
                    ans+=Kth(rt[xt],k);
                    cnt++;
                }
            }
            printf("Case %d: %.6f
    ",casen++,ans*1.0/cnt);
            REP(i,1,n) Free(rt[i]);
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    Canvas鼠标点击特效(富强、民主...)、收藏
    mysql实现当前行的值累加上一行的值
    HTML生成横向的PDF
    Java iText+FreeMarker生成PDF(HTML转PDF)
    HTML图片点击放大---关闭
    HTML页面通过JS跨域调用,子传父
    查询结果中出现行号(适用于按名次排序)
    在Nginx和Apache服务器配置https
    Rinetd 端口转发工具
    lsyncd使用中遇到的问题
  • 原文地址:https://www.cnblogs.com/--560/p/5240032.html
Copyright © 2011-2022 走看看