#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;
}
6962-I love tree(待补)
最新推荐文章于 2021-11-07 16:49:01 发布