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

HYSBZ 2243

时间:2015-05-29 20:18:04      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
//Accepted    18440 KB    5556 ms
/*
    source:HYSBZ 2243
    time  :2015.5.29
    by    :songt
  */
/*题解:
树链剖分

  */

#include <cstdio>
#include <cstring>

const int imax_n = 100005;
struct Edge
{
    int u,v;
    Edge(){}
    Edge(int u,int v):u(u),v(v){}
}edge[2*imax_n];
int head[imax_n];
int next[2*imax_n];
int tot;
int top[imax_n];
int son[imax_n];
int num[imax_n];
int p[imax_n];
int fp[imax_n];
int deep[imax_n];
int fa[imax_n];
int pos;

void init()
{
    memset(head,-1,sizeof(head));
    memset(next,-1,sizeof(next));
    tot=0;
    memset(son,-1,sizeof(son));
    pos=0;
}

void addEdge(int u,int v)
{
    edge[tot]=Edge(u,v);
    next[tot]=head[u];
    head[u]=tot++;
}

void dfs1(int u)
{
    num[u]=1;
    for (int i=head[u];i+1;i=next[i])
    {
        int v=edge[i].v;
        if (v!=fa[u])
        {
            fa[v]=u;
            deep[v]=deep[u]+1;
            dfs1(v);
            num[u]+=num[v];
            if (son[u]==-1 || num[son[u]]<num[v])
                son[u]=v;
        }
    }
}

void dfs2(int u)
{
    p[u]=pos++;
    fp[p[u]]=u;
    if (son[u]==-1) return ;
    top[son[u]]=top[u];
    dfs2(son[u]);
    for (int i=head[u];i+1;i=next[i])
    {
        int v=edge[i].v;
        if (v!=son[u] && v!=fa[u])
        {
            dfs2(top[v]=v);
        }
    }
}

struct Tree
{
    int l,r;
    int lc,rc;
    int num;
    int same;
    int color;
}f[imax_n*3];
int color[imax_n];

void push_down(int t)
{
    f[2*t].same=f[2*t+1].same=1;
    f[2*t].color=f[2*t+1].color=f[t].color;
    f[2*t].num=f[2*t+1].num=1;
    f[2*t].lc=f[2*t].rc=f[t].color;
    f[2*t+1].lc=f[2*t+1].rc=f[t].color;
    f[t].same=0;
}

void push_up(int t)
{
    f[t].num=f[2*t].num+f[2*t+1].num-(f[2*t].rc==f[2*t+1].lc);
    f[t].lc=f[2*t].lc;
    f[t].rc=f[2*t+1].rc;
}

void build(int t,int l,int r)
{
    f[t].l=l;
    f[t].r=r;
    f[t].same=0;
    if (l==r)
    {
        f[t].lc=f[t].rc=color[fp[l]];
        f[t].color=color[fp[l]];
        f[t].num=1;
        f[t].same=1;
        return ;
    }
    int mid=(f[t].l+f[t].r)>>1;
    build(2*t,l,mid);
    build(2*t+1,mid+1,r);
    push_up(t);
}

void update(int t,int l,int r,int color)
{
    if (f[t].l==l && f[t].r==r)
    {
        f[t].color=color;
        f[t].num=1;
        f[t].lc=f[t].rc=color;
        f[t].same=1;
        return ;
    }
    if (f[t].same) push_down(t);
    int mid=(f[t].l+f[t].r)>>1;
    if (r<=mid) update(2*t,l,r,color);
    else
    {
        if (l>mid) update(2*t+1,l,r,color);
        else
        {
            update(2*t,l,mid,color);
            update(2*t+1,mid+1,r,color);
        }
    }
    push_up(t);
}

int query(int t,int l,int r,int &cl,int &rl)
{
    if (f[t].l==l && f[t].r==r)
    {
        cl=f[t].lc;
        rl=f[t].rc;
        return f[t].num;
    }
    if (f[t].same) push_down(t);
    int mid=(f[t].l+f[t].r)>>1;
    if (r<=mid) return query(2*t,l,r,cl,rl);
    else
    {
        if (l>mid) return query(2*t+1,l,r,cl,rl);
        else
        {
            int lcl,lcr,rcl,rcr;
            int numl,numr;
            numl=query(2*t,l,mid,lcl,lcr);
            numr=query(2*t+1,mid+1,r,rcl,rcr);
            cl=lcl;
            rl=rcr;
            return numl+numr-(lcr==rcl);
        }
    }
}

void swap(int &a,int &b)
{
    int t=a;
    a=b;
    b=t;
}

void OpC(int u,int v,int c)
{
    int f1=top[u],f2=top[v];
    while (f1!=f2)
    {
        //printf("u=%d v=%d top[u]=%d top[v]=%d\n",u,v,f1,f2);
        if (deep[f1]<deep[f2])
        {
            swap(f1,f2);
            swap(u,v);
        }
        update(1,p[f1],p[u],c);
        //printf("update %d %d\n",f1,u);
        u=fa[f1];
        f1=top[u];
    }
    if (deep[u]>deep[v]) swap(u,v);
    update(1,p[u],p[v],c);
    //printf("update %d %d\n",u,v);
}

int OpQ(int u,int v)
{
    int f1=top[u],f2=top[v];
    int cu=-1,cv=-1;
    int ans=0;
    int lc,rc;
    while (f1!=f2)
    {
        if (deep[f1]<deep[f2])
        {
            swap(f1,f2);
            swap(u,v);
            swap(cu,cv);
        }
        int tmp=query(1,p[f1],p[u],lc,rc);
        //printf("%d %d num=%d lc=%d rc=%d\n",f1,u,tmp,lc,rc);
        ans+=tmp;
        ans-=(cu==rc);
        cu=lc;
        u=fa[f1];
        f1=top[u];
    }
    if (deep[u]>deep[v])
    {
        swap(u,v);
        swap(cu,cv);
    }
    int tmp=query(1,p[u],p[v],lc,rc);
    //printf("%d %d num=%d lc=%d rc=%d\n",u,v,tmp,lc,rc);
    ans+=query(1,p[u],p[v],lc,rc);
    ans-=(cu==lc);
    ans-=(cv==rc);
    return ans;
}

int n,m;
char op[10];
int u,v,c;

int main()
{
    //while (scanf("%d%d",&n,&m)==2)
    scanf("%d%d",&n,&m);
    {
        init();
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&color[i]);
        }
        for (int i=0;i<n-1;i++)
        {
            scanf("%d%d",&u,&v);
            addEdge(u,v);
            addEdge(v,u);
        }
        fa[1]=0;
        deep[1]=0;
        dfs1(1);
        dfs2(top[1]=1);
        build(1,0,pos-1);
        for (int i=0;i<m;i++)
        {
            scanf("%s",op);
            if (op[0]==Q)
            {
                scanf("%d%d",&u,&v);
                printf("%d\n",OpQ(u,v));
            }
            else
            {
                scanf("%d%d%d",&u,&v,&c);
                OpC(u,v,c);
            }
        }
    }
    return 0;
}
View Code

 

HYSBZ 2243

标签:

原文地址:http://www.cnblogs.com/djingjing/p/4539287.html

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