BZOJ3589: 动态树

来源:互联网 发布:手机天网视频软件 编辑:程序博客网 时间:2024/05/24 07:25

树链剖分。。
沃日打错树剖+路径并
感觉要滚粗啊

#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>using namespace std;#define ll long longconst  ll Mod=1ll<<31;char c;inline void read(ll &a){    a=0;do c=getchar();while(c<'0'||c>'9');    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}struct Chain{    Chain *next;    ll u;}*Head[300001];#define ll long longll Dep[300001];namespace LC{ll Len[600001];ll ST[1000001][20];ll In[600001];ll Block[600001];ll tot;inline ll L(ll x,ll y){return Dep[x]<Dep[y]?x:y;}inline ll LCA(ll a,ll b){    if(!(a^b))return a;    ll x=In[a],y=In[b];    if(x>y)swap(x,y);    ll Len=y-x+1,Bl=Block[Len];    return L(ST[x][Bl],ST[y-(1<<Bl)+1][Bl]);}ll Dis(ll u,ll v){return Len[u]+Len[v]-2*Len[LCA(u,v)];}inline void Bg(){    Len[0]=1ll<<29;    Dep[0]=1ll<<29;    ll base;      for(ll i=1,base=1;i<=19;i++,base<<=1)         for(ll j=1;j<=tot;j++)             ST[j][i]=L(ST[j][i-1],ST[j+base][i-1]);    ll con=0;    for(ll i=1;i<=tot;i++)      if(i^(i&-i))Block[i]=con-1;      else Block[i]=con++;}void DFS(ll u,ll fa,ll dep){    Dep[u]=dep;    ST[In[u]=++tot][0]=u;    for(Chain*tp=Head[u];tp;tp=tp->next)      if(tp->u^fa)       {         DFS(tp->u,u,dep+1);         ST[++tot][0]=u;       }     if(u^fa)return ;    Bg();}}ll t;namespace Seg{  struct N  {    ll l,r;    ll sum,flag;  }T[600001];  inline void Build(ll place,ll l,ll r)  {    ll Mid=l+r>>1,lc=place<<1,rc=lc|1;    T[place].l=l,T[place].r=r;    if(l^r)      Build(lc,l,Mid),Build(rc,Mid+1,r);  }  inline void AddFlag(ll place,ll Delta)  {    T[place].flag+=Delta,T[place].sum+=Delta*(T[place].r-T[place].l+1);    T[place].flag%=Mod,T[place].sum%=Mod;  }  inline void pushdown(ll place)  {    ll lc=place<<1,rc=lc|1;    T[lc].flag+=T[place].flag,T[rc].flag+=T[place].flag;    T[lc].sum+=T[place].flag*(T[lc].r-T[lc].l+1),    T[rc].sum+=T[place].flag*(T[rc].r-T[rc].l+1);    T[lc].flag%=Mod;T[rc].flag%=Mod;    T[lc].sum%=Mod;T[rc].sum%=Mod;    T[place].flag=0;   }  void Add(ll place,ll l,ll r,ll Delta)  {    if(T[place].l>=l&&T[place].r<=r)      { AddFlag(place,Delta);return;}//      if(T[place].flag)pushdown(place);    ll lc=place<<1,rc=lc|1,Mid=T[lc].r;    if(Mid<r)Add(rc,l,r,Delta);    if(Mid>=l)Add(lc,l,r,Delta);    T[place].sum=(T[lc].sum+T[rc].sum+T[place].flag*(T[place].r-T[place].l+1))%Mod;  }  ll Query(ll place,ll l,ll r)  {    if(T[place].l>=l&&T[place].r<=r)return T[place].sum;//    if(T[place].flag)pushdown(place);    ll res=T[place].flag*(min(r,T[place].r)-max(l,T[place].l)+1),lc=place<<1,rc=lc|1,Mid=T[lc].r;     if(l<=Mid)res+=Query(lc,l,r);     if(r>Mid)res+=Query(rc,l,r);    res%=Mod;    return res;  }}struct Path{ll f,s;};Path operator &(Path a,Path b){    Path res;    res.f=LC::LCA(a.f,b.f);    if(res.f==b.f)res.f=a.f;    else if(res.f==a.f)res.f=b.f;    else return (Path){-1,-1};    res.s=LC::LCA(a.s,b.s);    if(Dep[res.f]>Dep[res.s])return (Path){-1,-1};    return res;}ll K;Path X[30001];ll HeavySon[300001],Size[300001],F[300001];void DFS(ll u,ll f){    Size[u]++;    F[u]=f;    for(Chain *tp=Head[u];tp;tp=tp->next)      if(tp->u!=f)        {            DFS(tp->u,u);            Size[u]+=Size[tp->u];            if(Size[tp->u]>Size[HeavySon[u]])HeavySon[u]=tp->u;        }}ll tot,CBG[300001],CED[300001],CPL[300001],CND[300001];void DFS2(ll u,ll f,ll BG){    CBG[u]=BG;    CND[CPL[u]=++tot]=u;    if(HeavySon[u])      DFS2(HeavySon[u],u,BG);    for(Chain *tp=Head[u];tp;tp=tp->next)     if(tp->u!=HeavySon[u]&&tp->u!=f)       DFS2(tp->u,u,tot+1);    CED[u]=tot;}ll Query(Path X){    ll res=0,u=X.f,v=X.s;    while(CBG[v]!=CBG[u])    {        res+=Seg::Query(1,CBG[v],CPL[v]);        v=F[CND[CBG[v]]];    }  res+=Seg::Query(1,CPL[u],CPL[v]);  return res;}ll Add(ll u,ll Delta){    Seg::Add(1,CPL[u],CED[u],Delta);}ll Div(ll x,Path Tp){    if(x==K+1)return 0;    if(Tp.f==4&&Tp.s==4)     x++,x--;    if(Tp.f==-1)return 0;    ll res=Query(Tp);    for(ll i=x+1;i<=K;i++)    res-=Div(i,Tp&X[i]),res%=Mod;    return res%Mod;}inline void ADD(ll a,ll b){    Chain *tp=new Chain;    tp->u=b,tp->next=Head[a],Head[a]=tp;} ll n,Q ;int main(){    read(n);    ll i,j,k,l;    for(i=1;i<n;i++)    {        read(j),read(k),ADD(j,k),ADD(k,j);    }    LC::DFS(1,1,1);    DFS(1,1);    DFS2(1,1,1);    Seg::Build(1,1,tot);    read(Q);    while(Q--)    {        ll op;        read(op);        if(op)        {          read(K);          ll ans=0,j,k;           for(i=1;i<=K;i++)             {                read(j),read(k);                X[i].f=Dep[j]<Dep[k]?j:k;                X[i].s=j+k-X[i].f;             }          for(i=1;i<=K;i++)           ans+=Div(i,X[i]);        printf("%lld\n",(ans%Mod+Mod)%Mod);       }       else read(j),read(k),Add(j,k);    }//  printf("%d\n",t);    return 0;}
0 0
原创粉丝点击