POJ 2763 树链剖分 或LCA加树状数组

地址

树链剖分

//#include <bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 100005
#define M 4000009

#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long  ll;
typedef double db;
const ll  mod=1e9+7;
struct edge
{
    int d,next;
    edge():next(-1){}
}e[2*N];
struct node
{
    int st,go,t;
    node(){}
    node(int s,int x,int y):st(s),go(x),t(y){}
}num[N];
int f[N],d[N],siz[N],son[N],rk[N],top[N],id[N],a[N],n;
int t[3*N],add[3*N],head[N];
int which=1;
void add1(int s,int d)
{
    e[which].d=d;
    e[which].next=head[s];
    head[s]=which++;
}
void down(int r,int st,int ed)
{
    if(add[r])
    {
        add[r<<1]=add[r];
     //   add[r<<1]%=p;
        add[r<<1|1]=add[r];
     //   add[r<<1|1]%=p;
        int mid=(st+ed)>>1;
        t[r<<1]=add[r]*(mid-st+1);
        t[r<<1|1]=add[r]*(ed-mid);
      //  t[r<<1]%=p;
     //   t[r<<1|1]%=p;
        add[r]=0;
    }
}
void build(int r,int st,int ed)
{
    if(st==ed) t[r]=a[rk[st]];
    else
    {
        int mid=(st+ed)>>1;
        build(r<<1,st,mid);
        build(r<<1|1,mid+1,ed);
        t[r]=t[r<<1]+t[r<<1|1];
    }
}
void update(int r,int st,int ed,int x,int y,int z)
{
    if(st>y||ed<x) return ;
    if(st>=x&&ed<=y)
    {
        add[r]=z;
    //    add[r]%=p;
        t[r]=z*(ed-st+1);
    //    t[r]%=p;
        return ;
    }
    down(r,st,ed);
    int mid=(st+ed)>>1;
    update(r<<1|1,mid+1,ed,x,y,z);
    update(r<<1,st,mid,x,y,z);
    t[r]=t[r<<1]+t[r<<1|1];
   // t[r]%=p;
}
int findm(int r,int st,int ed,int x,int y)
{
    if(st>y||ed<x) return 0;
    if(st>=x&&ed<=y) return t[r];
    down(r,st,ed);
    int mid=(st+ed)>>1;
    return (findm(r<<1,st,mid,x,y)+findm(r<<1|1,mid+1,ed,x,y));
}
void dfs1(int x,int fa,int dep)
{
    f[x]=fa;
    siz[x]=1;
    d[x]=dep;
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        int to=e[i].d;
        if(to!=fa)
        {
            dfs1(to,x,dep+1);
            siz[x]+=siz[to];
            if(siz[to]>siz[son[x]]) son[x]=to;
        }
    }
}
int cnt;
void dfs2(int x,int t)
{
    top[x]=t;
    id[x]=++cnt;
    rk[cnt]=x;
    if(!son[x]) return ;
    dfs2(son[x],t);
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        int to=e[i].d;
        if(to!=son[x]&&to!=f[x]) dfs2(to,to);
    }
}
int sum(int x,int y)
{
    int ans=0,fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(d[fx]>d[fy])
        {
            ans+=findm(1,1,n,id[fx],id[x]);
            x=f[fx];
       //     ans%=p;
        }
        else
        {
            ans+=findm(1,1,n,id[fy],id[y]);
            y=f[fy];
       //     ans%=p;
        }
        fx=top[x];
        fy=top[y];
    }
    if(x==y) return ans;
    if(id[x]<=id[y]) ans+=findm(1,1,n,id[son[x]],id[y]);
    else ans+=findm(1,1,n,id[son[y]],id[x]);
    return ans;
}
void updateson(int x,int y,int c)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(d[fx]>=d[fy])
        {
            update(1,1,n,id[fx],id[x],c);
            x=f[fx];
        }
        else
        {
            update(1,1,n,id[fy],id[y],c);
            y=f[fy];
        }
        fx=top[x];
        fy=top[y];
    }
    if(id[x]<=id[y]) update(1,1,n,id[x],id[y],c);
    else update(1,1,n,id[y],id[x],c);
}
int main()
{
    int m,r;
    mem(head,-1);
    sddd(n,m,r);
    fup(i,1,n-1)
    {
        int x,y,z;
        sddd(num[i].st,num[i].go,num[i].t);
        x=num[i].st,y=num[i].go;
        add1(x,y);
        add1(y,x);
    }
    dfs1(1,0,1);
    dfs2(1,1);
  //  puts("1");
    fup(i,1,n-1)
    {
        int x=num[i].st,y=num[i].go;
        if(d[x]<d[y]) swap(x,y),swap(num[i].st,num[i].go);
        a[x]=num[i].t;
    }
    build(1,1,n);
    while(m--)
    {

        int op,x,y,z;
        sd(op);
        if(op==0)
        {
            sd(x);
            pf(sum(r,x));
            r=x;
        }
        else
        {
            sdd(x,z);
            x=num[x].st;
            update(1,1,n,id[x],id[x],z);
        }
    }
    return 0;
}

/*
66928 66992
67095 71145
*/

LCA加树状数组

//#include <bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define fil(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define debug printf("!!\n");
#define N 100005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);// freopen("in.txt","r",stdin);
using namespace std;
typedef long long  ll;
typedef double db;
int n,s;
struct node
{
    int go,t;
    node(int a,int b)
    {
        go=a;
        t=b;
    }
};
struct node1
{
    int x,y,z;
}num[N];
int fa[N],deep[N],dp[N][20],dis[N],st[N],ed[N],change[N];
vector<node> q[N];
int id;
void dfs(int x,int dep)
{
    st[x]=++id;
    deep[x]=dep;
    dp[x][0]=fa[x];
    for(int i=1;(1<<i)<deep[x];i++)
        dp[x][i]=dp[dp[x][i-1]][i-1];
    for(int i=0;i<q[x].size();i++)
    {
        node tp=q[x][i];
        if(tp.go!=fa[x])
        {
            dis[tp.go]=dis[x]+tp.t;
            fa[tp.go]=x;
            dfs(tp.go,dep+1);
        }
    }
    ed[x]=id+1;
}
int lca(int a,int b)
{
    if(deep[a]>deep[b]) swap(a,b);
    int k=deep[b]-deep[a];

    for(int i=0;i<=19;i++)
        if((1<<i)&k) b=dp[b][i];


    for(int i=19;i>=0;i--)
        if(dp[a][i]!=dp[b][i]) a=dp[a][i],b=dp[b][i];
    if(a==b) return a;
    return dp[a][0];
}
void add(int i,int x)
{
    while(i<=n+1)
    {
        change[i]+=x;
        i+=lowbit(i);
    }
}
int cal(int i)
{
    int ans=0;
    while(i>0)
    {
        ans+=change[i];
        i-=lowbit(i);
    }
    return ans;
}
void solve()
{

    int tt,m,s;
    sddd(n,m,s);
        id=0;
        fup(i,1,n-1)
        {
            int x,y,z;
            sddd(x,y,z);
            q[x].push_back(node(y,z));
            q[y].push_back(node(x,z));
            num[i].x=x;
            num[i].y=y;
            num[i].z=z;
        }
        dfs(s,1);
        while(m--)
        {
            int x,y,f;
            sd(f);
            if(!f)
            {
                sd(x);
                int clo=lca(s,x);
                int res=cal(st[s])+cal(st[x])-2*cal(st[clo]);
                pf(dis[x]+dis[s]-2*dis[clo]+res);
                s=x;
            }
            else
            {
                sdd(x,y);
                if(fa[num[x].x]==num[x].y)  swap(num[x].x,num[x].y);
                add(st[num[x].y],y-num[x].z);
                add(ed[num[x].y],-y+num[x].z);
                num[x].z=y;
            }
        }
}
//
int main()
{
    int t=1;
   // sd(t);
    while(t--)
    {
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值