6962-I love tree(待补)

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define IO ios::sync_with_stdio(false)
#define bug cout << "-----\n"
typedef long long ll;
const int N = 100010;
const int M = 500010;
int cnt = 0,ans = 0;
int id[N],ne[N],top[N],son[N],f[N],d[N],siz[N],a[N];
vector<int> vt[N];
struct Tree {
    int x,l,r,num,lazy;
}tree1[N << 2],tree2[N << 2],tree3[N << 2];
void build(int x,int l,int r,Tree *tree) {
    tree[x].l = l;tree[x].r = r;
    if(l == r) {
        tree[x].num = 0;
        return ;
    }
    int mid = l + r >> 1;
    build(x << 1 , l , mid , tree);
    build(x << 1 | 1 , mid + 1 , r , tree);
}

void pushdown(int x,Tree *tree) {
    int t = tree[x].lazy;
    if(t) {
        tree[x << 1].lazy += t;
        tree[x << 1 | 1].lazy += t;
        tree[x << 1].num += (tree[x << 1].r - tree[x << 1].l + 1) * t;
        tree[x << 1 | 1].num += (tree[x << 1 | 1].r - tree[x << 1 | 1].l + 1) * t;
        tree[x].lazy = 0;
    }
}

void update(int x,int l,int r,int t,Tree *tree) {
    if(tree[x].l >= l && tree[x].r <= r) {
        tree[x].lazy += t;
        tree[x].num += (tree[x].r - tree[x].l + 1) * t;
        return ;
    }
    pushdown(x,tree);
    if(r <= tree[x << 1].r)update(x << 1 , l , r , t , tree);
    else if(l >= tree[x << 1 | 1].l)update(x << 1 | 1 , l , r , t , tree);
    else {
        update(x << 1 , l , tree[x << 1].r ,t , tree);
        update(x << 1 | 1 , tree[x << 1 | 1].l , r , t , tree);
    }
    tree[x].num = tree[x << 1].num + tree[x << 1 | 1].num;
}

void find(int x,int l,int r,Tree * tree) {
    if(tree[x].l >= l && tree[x].r <= r) {
        ans += tree[x].num;
        return ;
    }
    pushdown(x,tree);
    if(r <= tree[x << 1].r)find(x << 1 , l , r , tree);
    else if(l >= tree[x << 1 | 1].l)find(x << 1 | 1 , l , r , tree);
    else {
        find(x << 1 , l , tree[x << 1].r , tree);
        find(x << 1 | 1 , tree[x << 1 | 1].l , r , tree);
    }
    tree[x].num = tree[x << 1 ].num + tree[x << 1 | 1].num;
}

void dfs1(int x,int fa,int deap) {
    int i;
    f[x] = fa;
    d[x] = deap;
    siz[x] = 1;
    int bigson = -1;
    for(i = 0 ; i < vt[x].size() ; i ++) {
        int t = vt[x][i];
        if(t == fa)continue;
        dfs1(t , x , deap + 1);
        siz[x] += siz[t];
        if(siz[t] > bigson)bigson = siz[t] , son[x] = t;
    }
}

void dfs2(int x,int tp) {
    int i;
    id[x] = ++ cnt;
    ne[cnt] = a[x];
    top[x] = tp;
    if(!son[x])return ;
    dfs2(son[x] , tp);
    for(i = 0 ; i < vt[x].size() ; i ++) {
        int t = vt[x][i];
        if(t == f[x] || t == son[x])continue;
        dfs2(t , t);
    }
}
int lca(int x,int y) {
    while(top[x] != top[y]) {
        if(d[top[x]] < d[top[y]])y = f[top[y]];
        else x = f[top[x]];
    }
    if(d[x] > d[y])return y;
    return x;
}
void Addupdate(int x,int y,Tree *tree) {
    cout << x << endl;
    int p = lca(x , y);
    int l = 1,r = d[x] + d[y] - 2 * d[p] + 1;
    while(top[x] != top[y]) {
        if(d[top[x]] > d[top[y]]) {
            ll add = l + id[x];
            l += d[x] - d[top[x]];
            update(1 , id[top[x]] , id[x] , 1 , tree1);
            update(1 , id[top[x]] , id[x] , add , tree2);
            update(1 , id[top[x]] , id[x] , add * add , tree3);
            x = f[top[x]];
            l ++;
        }
        else {
            r -= d[y] - d[top[y]];
            ll add = id[top[y]] - r;
            update(1 , id[top[y]] , id[y] , 1 , tree1);
            update(1 , id[top[y]] , id[y] , add , tree2);
            update(1 , id[top[y]] , id[y] , add * add , tree3);
            y = f[top[y]];
            r --;
        }
    }
    if(d[x] > d[y]) {
        ll add = id[x] + l;
        update(1 , id[y] , id[x] , 1 , tree1);
        update(1 , id[y] , id[x] , add , tree2);
        update(1 , id[y] , id[x] , add * add , tree3);
    }
    else {
        ll add = id[x] - l;
        update(1 , id[x] , id[y] , 1 , tree1);
        update(1 , id[x] , id[y] , add , tree2);
        update(1 , id[x] , id[y] , add * add , tree3);
    }
}


int main() {
    int n,m,i,j,k,x,y,z,c;
    cin >> n;
    for(i = 1 ; i < n ; i ++) {
        cin >> x >> y;
        vt[x].push_back(y);
        vt[y].push_back(x);
    }
    dfs1(1 , 0 , 1);dfs2(1 , 1);
    build(1 , 1 , n , tree1);build(1 , 1 , n , tree2);build(1 , 1 , n , tree2);
    cin >> m;
    while(m --){
        cin >> c;
        if(c == 1) {
            cin >> x >> y;
            Addupdate(x , y , tree1);
            Addupdate(x , y , tree2);
            Addupdate(x , y , tree3);
        }
        else if(c == 2) {
            cin >> x;
            //cout << "----" << id[x] << endl;
            ans = 0;
            find(1 , id[x] , id[x] , tree1);
            ll x1 = ans;
            ans = 0;
            find(1 , id[x] , id[x] , tree2);
            ll x2 = ans;
            ans = 0;
            find(1 , id[x] , id[x] , tree3);
            ll x3 = ans;
            cout << id[x] * id[x] * x1 - 2 * id[x] * x2 + x3 << endl;
        }
    }
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值