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!
  • 相关阅读:
    IXmlSerializable With WCFData Transfer in Service Contracts
    Difference Between XmlSerialization and BinarySerialization
    Using XmlSerializer (using Attributes like XmlElement , XmlAttribute etc ) Data Transfer in Service Contracts
    Introducing XML Serialization
    Version Tolerant Serialization
    Which binding is bestWCF Bindings
    Data Transfer in Service Contracts
    DataContract KnownTypeData Transfer in Service Contracts
    Using the Message ClassData Transfer in Service Contracts
    DataContract POCO SupportData Transfer in Service Contracts
  • 原文地址:https://www.cnblogs.com/--560/p/5240032.html
Copyright © 2011-2022 走看看