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!
原文地址:https://www.cnblogs.com/--560/p/5240032.html