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

树链剖分 月下毛景树

时间:2016-01-16 09:41:35      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:

未完成

#include<cstdio>
#include<iostream>
using namespace std;
struct ss
{
 int l,r,gai,jia,zhi;
} shu[400008];
int n,head[100005],next[200005],u[200005],v[200006],cnt=1,id[100005];
int deep[100005],size[100005],lc[100005][20],n1,dui[100005],lian[100005];
void jiabian(int a1,int a2,int a3)
{
 cnt++;
 next[cnt]=head[a1];
 head[a1]=cnt;
 u[cnt]=a2;
 v[cnt]=a3;
 return;
}
void shu1(int a1)
{
 printf("%d %d %d %d %d\n",shu[a1].l,shu[a1].r,shu[a1].zhi,shu[a1].gai,shu[a1].jia);
 if(shu[a1].l==shu[a1].r)
   return;
 shu1(a1*2);
 shu1(a1*2+1);
 return;
}
void gengxin(int a1)
{
 if(shu[a1].l==shu[a1].r)
   return;
 if(shu[a1].gai!=-1)
   {
    shu[a1<<1].zhi=shu[a1<<1|1].zhi=shu[a1].gai;
    shu[a1<<1].gai=shu[a1<<1|1].gai=shu[a1].gai;
    shu[a1<<1].jia=shu[a1<<1|1].jia=0;
    shu[a1].gai=-1;
   }
 if(shu[a1].jia!=0)
   {
    shu[a1*2].zhi+=shu[a1].jia;
    if(shu[a1*2].gai==-1)
      shu[a1*2].jia+=shu[a1].jia;
    else
      shu[a1*2].gai+=shu[a1].jia;
    if(shu[a1*2+1].gai==-1)
      shu[a1*2+1].jia+=shu[a1].jia;
    else
      shu[a1*2+1].gai+=shu[a1].jia;
    shu[a1<<1|1].zhi+=shu[a1].jia;
    shu[a1].jia=0;
   }
}
void xianjia(int a1,int a2,int a3,int a4)
{
 if(shu[a1].l>=a2&&shu[a1].r<=a3)
   {
    shu[a1].zhi+=a4;
    if(shu[a1].gai!=-1)
      shu[a1].gai+=a4;
    else
      shu[a1].jia+=a4;
    return;
   }
 gengxin(a1);
 int mid=(shu[a1].l+shu[a1].r)>>1;
 if(a2<=mid)
   xianjia(a1<<1,a2,a3,a4);
 if(a3>mid)
   xianjia(a1<<1|1,a2,a3,a4);
    shu[a1].zhi=max(shu[a1<<1].zhi,shu[a1<<1|1].zhi);
    return;
}
void build(int a1,int a2,int a3)
{
 shu[a1].l=a2;
 shu[a1].r=a3;
 shu[a1].gai=-1;
 if(a2==a3)
   return;
 int mid=(a2+a3)>>1;
 build(a1<<1,a2,mid);
 build(a1<<1|1,mid+1,a3);
 return;
}
void dfs1(int a1,int a2)
{
 size[a1]=1;
 for(int i=1;i<=16;i++)
   {
    if(deep[a1]<1<<i)
      break;
    lc[a1][i]=lc[lc[a1][i-1]][i-1];
   }
 for(int i=head[a1];i;i=next[i])
   if(u[i]!=a2)
     {
      deep[u[i]]=deep[a1]+1;
      lc[u[i]][0]=a1;
      dfs1(u[i],a1);
      size[a1]+=size[u[i]];
  }
 return;
}
void dfs2(int a1,int a2)
{
 n1++;
 dui[a1]=n1;
 lian[a1]=a2;
 int k=0;
 for(int i=head[a1];i;i=next[i])
   if(deep[a1]<deep[u[i]])
     {
      if(size[u[i]]>size[k])
        k=u[i];
  }
   else
     {
       xianjia(1,dui[a1],dui[a1],v[i]);
       id[i>>1]=a1;
       //shu1(1);
       //printf("\n");
     }
 if(k==0)
   return;
 dfs2(k,a2);
 for(int i=head[a1];i;i=next[i])
   if(deep[a1]<deep[u[i]]&&k!=u[i])
     dfs2(u[i],u[i]);
}
int lca(int a1,int a2)
{
 if(deep[a1]<deep[a2])
   swap(a1,a2);
 int t=deep[a1]-deep[a2];
 for(int i=0;i<=16;i++)
   if(t&(1<<i))
     a1=lc[a1][i];
 for(int i=16;i>=0;i--)
   if(lc[a1][i]!=lc[a2][i])
     {
      a1=lc[a1][i];
      a2=lc[a2][i];
  }
 if(a1==a2)
   return a1;
 else
   return lc[a1][0];
}
void lianjia(int a1,int a2,int a3)
{
 for(;lian[a1]!=lian[a2];)
   {
    xianjia(1,dui[lian[a1]],dui[a1],a3);
    a1=lc[lian[a1]][0];
   }
 if(dui[a2]+1<=dui[a1])
   xianjia(1,dui[a2]+1,dui[a1],a3);
 return;
}
void xiangai(int a1,int a2,int a3,int a4)
{
 if(shu[a1].l>=a2&&shu[a1].r<=a3)
   {
    shu[a1].zhi=a4;
    shu[a1].gai=a4;
    return;
   }
 gengxin(a1);
 int mid=(shu[a1].l+shu[a1].r)>>1;
 if(a2<=mid)
   xiangai(a1<<1,a2,a3,a4);
 if(a3>mid)
   xiangai(a1<<1|1,a2,a3,a4);
    shu[a1].zhi=max(shu[a1<<1].zhi,shu[a1<<1|1].zhi);
    return;
}
void liangai(int a1,int a2,int a3)
{
 for(;lian[a1]!=lian[a2];)
   {
    xiangai(1,dui[lian[a1]],dui[a1],a3);
    a1=lc[lian[a1]][0];
   }
 if(dui[a2]+1<=dui[a1])
   xiangai(1,dui[a2]+1,dui[a1],a3);
 return;
}
int xianmax(int a1,int a2,int a3)
{
 if(shu[a1].l>=a2&&shu[a1].r<=a3)
   return shu[a1].zhi;
 gengxin(a1);
 int mid=(shu[a1].l+shu[a1].r)>>1,ma=-2147483647;
 if(a2<=mid)
   ma=max(ma,xianmax(a1<<1,a2,a3));
 if(a3>mid)
   ma=max(ma,xianmax(a1<<1|1,a2,a3));
    return ma;
}
int lianzhao(int a1,int a2)
{
 int max1=-2147483647;
 for(;lian[a1]!=lian[a2];)
   {
    max1=max(max1,xianmax(1,dui[lian[a1]],dui[a1]));
    a1=lc[lian[a1]][0];
   }
 if(dui[a2]+1<=dui[a1])
   max1=max(max1,xianmax(1,dui[a2]+1,dui[a1]));
 return max1;
}
void xunwen()
{
 char ch[10];
 for(;1;)
 {
  int a1,a2,a3,t;
  scanf("%s",ch);
  if(ch[1]==‘t‘)
    return;
  scanf("%d%d",&a1,&a2);
  if(ch[1]==‘a‘)
    { 
      t=lca(a1,a2);
      printf("%d\n",max(lianzhao(a1,t),lianzhao(a2,t)));
    }
  if(ch[1]==‘d‘)
    {
      scanf("%d",&a3);
   t=lca(a1,a2);
   //printf("%d %d\n",t,t);
   lianjia(a1,t,a3);
   lianjia(a2,t,a3); 
    }
  if(ch[1]==‘o‘)
    {
     scanf("%d",&a3);
     t=lca(a1,a2);
    // printf("%d %d\n",t,t);
     liangai(a1,t,a3);
     liangai(a2,t,a3);
    }
  if(ch[1]==‘h‘)
  {
    xiangai(1,dui[id[a1]],dui[id[a1]],a2);
    //shu1(1);printf("\n");
     }
 }
}
int main()
{
 freopen("sj.txt","r",stdin);
 freopen("1.txt","w",stdout);
 scanf("%d",&n);
 for(int i=0;i<n-1;i++)
   {
    int a1,a2,a3;
    scanf("%d%d%d",&a1,&a2,&a3);
    jiabian(a1,a2,a3);
    jiabian(a2,a1,a3);
   }
 build(1,1,n);
 dfs1(1,0);
 dfs2(1,1);
 xunwen();
}

树链剖分 月下毛景树

标签:

原文地址:http://www.cnblogs.com/xydddd/p/5134895.html

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