hdu3726 Graph and Queries

重写了一遍,从TLE进不到WA了。。。我实在找不出错误在哪了。。。先放着,等过段时间刷顺利指南的时候再来看这题。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))
#define key_val ch[ch[rt[i]][1]][0]

using namespace std;

typedef long long ll;
const int maxn=2000100;
const int INF=1e9+10;

int n,m;
struct Query
{
    char op;int x,k;
};Query q[maxn];int qn;
struct Edge
{
    int u,v;
    bool exi;
};Edge e[maxn];
char ops[20];int x;ll k;
ll vp[maxn];
int fa[maxn];
int u,v;

int pre[maxn],sz[maxn],ch[maxn][2],rt[maxn],tot1;
int s[maxn],tot2;
ll val[maxn];

int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}

void Init()
{
    pre[0]=sz[0]=ch[0][0]=ch[0][1]=tot1=tot2=s[0]=val[0]=0;
    MS0(rt);
}

void newnode(int &r,int fa,ll k)
{
    if(tot2) r=s[tot2--];
    else r=++tot1;
    pre[r]=fa;val[r]=k;
    MS0(ch[r]);
    sz[r]=1;
}

void up(int r)
{
    sz[r]=sz[ch[r][0]]+sz[ch[r][1]]+1;
}

void rot(int x,int kind)
{
    int y=pre[x];
    ch[y][kind^1]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];
    ch[x][kind]=y;
    pre[y]=x;
    up(y);
}

void splay(int i,int x,int goal)
{
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x);
        else{
            int y=pre[x],z=pre[y];
            int kind=ch[y][0]==x,one=0;
            if(ch[y][0]==x&&ch[z][0]==y) one=1;
            if(ch[y][1]==x&&ch[z][1]==y) one=1;
            if(one) rot(y,kind),rot(x,kind);
            else rot(x,kind),rot(x,kind^1);
        }
    }
    if(goal==0) rt[i]=x;
    up(x);
}

void Insert(int i,ll x)
{
    int r=rt[i];
    if(r==0){
        newnode(rt[i],0,x);
        return;
    }
    while(ch[r][x>val[r]]) r=ch[r][x>val[r]];
    newnode(ch[r][x>val[r]],r,x);
    splay(i,ch[r][x>val[r]],0);
}

int get_pre(int r)
{
    r=ch[r][0];
    if(r==0) return 0;
    while(ch[r][1]) r=ch[r][1];
    return r;
}

int get_next(int r)
{
    r=ch[r][1];
    if(r==0) return 0;
    while(ch[r][0]) r=ch[r][0];
    return r;
}

void Erase(int r)
{
    if(r==0) return;
    Erase(ch[r][0]);
    Erase(ch[r][1]);
    s[++tot2]=r;
}

void Del(int i,ll x)
{
    int r=rt[i];
    while(val[r]!=x) r=ch[r][x>val[r]];
    splay(i,r,0);
    int pr=get_pre(r),qr=get_next(r);
    if(pr==0&&qr==0) Erase(r),rt[i]=0;
    else if(pr==0&&qr){
        s[++tot2]=r;
        rt[i]=ch[r][1];
        pre[rt[i]]=0;
    }
    else if(pr&&qr==0){
        s[++tot2]=r;
        rt[i]=ch[r][0];
        pre[rt[i]]=0;
    }
    else{
        splay(i,pr,0);splay(i,qr,rt[i]);
        Erase(key_val);
        key_val=0;
        up(ch[rt[i]][1]);up(rt[i]);
    }
}

ll Kth(int i,int k)
{
    int r=rt[i];
    if(r==0||k<=0||k>sz[r]) return 0;
    k=sz[r]+1-k;
    while(k-1!=sz[ch[r][0]]){
        if(k<sz[ch[r][0]]+1) r=ch[r][0];
        else k-=sz[ch[r][0]]+1,r=ch[r][1];
    }
    splay(i,r,0);
    return val[r];
}

void dfs(int r,int rty)
{
    if(r==0) return;
    dfs(ch[r][0],rty);
    dfs(ch[r][1],rty);
    Insert(rty,val[r]);
    s[++tot2]=r;
}

void Union(int u,int v)
{
    int x=find(u),y=find(v);
    if(x==y) return;
    if(sz[rt[x]]>sz[rt[y]]) swap(x,y);
    dfs(rt[x],y);
    rt[x]=0;
    fa[x]=y;
}

int main()
{
    freopen("in.txt","r",stdin);
    int casen=1;
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0) break;
        REP(i,1,n) fa[i]=i;
        Init();
        REP(i,1,n){
            scanf("%I64d",&vp[i]);
            Insert(i,vp[i]);
        }
        REP(i,1,m){
            scanf("%d%d",&u,&v);
            e[i]=(Edge){u,v,1};
        }
        qn=0;
        while(1){
            scanf("%s",ops);
            if(ops[0]=='E') break;
            ++qn;
            if(ops[0]=='D'){
                scanf("%d",&x);
                q[qn]=(Query){ops[0],x,0};
                e[x].exi=0;
            }
            else if(ops[0]=='Q'){
                scanf("%d%I64d",&x,&k);
                q[qn]=(Query){ops[0],x,k};
            }
            else{
                scanf("%d%I64d",&x,&k);
                q[qn]=(Query){ops[0],x,k};
            }
        }
        REP(i,1,m){
            if(e[i].exi){
                u=e[i].u,v=e[i].v;
                Union(u,v);
            }
        }
        ll ans=0,cnt=0;
        for(int i=qn;i>=1;i--){
            x=q[i].x,k=q[i].k;
            if(q[i].op=='D') Union(e[x].u,e[x].v);
            else if(q[i].op=='Q'){
                u=find(x);
                ans+=Kth(u,k);
                cnt++;
            }
            else{
                u=find(x);
                Del(u,vp[x]);
                vp[x]=k;
                Insert(u,k);
            }
        }
        printf("Case %d: %6f\n",casen++,ans*1.0/cnt);
    }
    return 0;
}
View Code

 

posted @ 2016-02-23 17:24  __560  阅读(339)  评论(0编辑  收藏  举报