码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5002 tree LCT

时间:2016-03-02 22:08:09      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

又是不小心打错一个字符调了一晚上。。。

技术分享
#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=1000010;
const int INF=1e9+10;

int n,m;
int pre[maxn],ch[maxn][2],rev[maxn],sz[maxn];
int val[maxn];
int fir[maxn],fircnt[maxn];
int sec[maxn],seccnt[maxn];
int add[maxn],cov[maxn];
int op,x,y,a,b,z;

bool isroot(int x)
{
    return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x;
}

void update_add(int x,int c)
{
    if(!x) return;
    val[x]+=c;
    add[x]+=c;
    fir[x]+=c;
    if(seccnt[x]) sec[x]+=c;
}

void update_cov(int x,int c)
{
    if(!x) return;
    val[x]=c;
    cov[x]=1;
    fir[x]=c;fircnt[x]=sz[x];
    sec[x]=-INF;seccnt[x]=0;
}

void update_rev(int x)
{
    if(!x) return;
    swap(ch[x][0],ch[x][1]);
    rev[x]^=1;
}

void down(int x)
{
    if(rev[x]){
        update_rev(ch[x][0]);
        update_rev(ch[x][1]);
        rev[x]=0;
    }
    if(add[x]){
        update_add(ch[x][0],add[x]);
        update_add(ch[x][1],add[x]);
        add[x]=0;
    }
    if(cov[x]){
        update_cov(ch[x][0],val[x]);
        update_cov(ch[x][1],val[x]);
        cov[x]=0;
    }
}

void P(int x)
{
    if(!isroot(x)) P(pre[x]);
    down(x);
}

void solve(int x,int v,int cnt)
{
    if(v>fir[x]) sec[x]=fir[x],seccnt[x]=fircnt[x],fir[x]=v,fircnt[x]=cnt;
    else if(v==fir[x]) fircnt[x]+=cnt;
    else if(v>sec[x]) sec[x]=v,seccnt[x]=cnt;
    else if(v==sec[x]) seccnt[x]+=cnt;
}

void up(int x)
{
    int l=ch[x][0],r=ch[x][1];
    sz[x]=sz[l]+sz[r]+1;
    fir[x]=-INF,fircnt[x]=0;
    sec[x]=-INF,seccnt[x]=0;
    solve(x,val[x],1);
    if(l) solve(x,fir[l],fircnt[l]),solve(x,sec[l],seccnt[l]);
    if(r) solve(x,fir[r],fircnt[r]),solve(x,sec[r],seccnt[r]);
}

void rot(int x,int kind)
{
    int y=pre[x];
    ch[y][kind^1]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(!isroot(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 x)
{
    P(x);
    while(!isroot(x)){
        if(isroot(pre[x])) 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);
        }
    }
    up(x);
}

int access(int x)
{
    int t=0;
    while(x){
        splay(x);
        ch[x][1]=t;
        t=x;x=pre[x];
        up(t);
    }
    return t;
}

void makeroot(int x)
{
    access(x);splay(x);update_rev(x);
}

void link(int x,int y)
{
    makeroot(x);pre[x]=y;
}

void cut(int x,int y)
{
    makeroot(x);access(y);splay(y);ch[y][0]=pre[x]=0;up(y);
}

void Cov(int x,int y,int z)
{
    makeroot(x);access(y);splay(y);update_cov(y,z);
}

void Add(int x,int y,int z)
{
    makeroot(x);access(y);splay(y);update_add(y,z);
}

void query(int x,int y)
{
    makeroot(x);access(y);splay(y);
    if(seccnt[y]==0) puts("ALL SAME");
    else printf("%d %d\n",sec[y],seccnt[y]);
}

int main()
{
    freopen("in.txt","r",stdin);
    int T;cin>>T;int casen=1;
    while(T--){
        scanf("%d%d",&n,&m);
        REP(i,0,n) pre[i]=rev[i]=add[i]=cov[i]=0,MS0(ch[i]);
        REP(i,1,n){
            scanf("%d",&val[i]);
            fir[i]=val[i];fircnt[i]=1;
            sec[i]=-INF,seccnt[i]=0;
            sz[i]=1;
        }
        REP(i,1,n-1){
            scanf("%d%d",&x,&y);
            link(x,y);
        }
        printf("Case #%d:\n",casen++);
        REP(i,1,m){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d%d",&x,&y,&a,&b);
                cut(x,y);
                link(a,b);
            }
            else if(op==2){
                scanf("%d%d%d",&x,&y,&z);
                Cov(x,y,z);
            }
            else if(op==3){
                scanf("%d%d%d",&x,&y,&z);
                Add(x,y,z);
            }
            else{
                scanf("%d%d",&x,&y);
                query(x,y);
            }
        }
    }
    return 0;
}
View Code

 

hdu5002 tree LCT

标签:

原文地址:http://www.cnblogs.com/--560/p/5236562.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!