Description
A tree and a right set of operations several times, the value of a start node tree is 0, the following operations are required:
So that x, y point right point on the route between the two points are multiplied by a number
So that x, y point right point on the path between two points are combined with a number
So x, y point on a point right between the two paths bitwise (~)
Query path between two points on the right of the point and
All of the answers are $ 2 ^ {64} $ modulo
Solution
Title Partition Tree chain.
With regard to $ 2 ^ {64} $ modulo, we might array as unsigned long long type, so that to achieve a natural overflow of the modulo number.
About the first two operations we maintain two markers to complete,
With regard to the third operation, that bitwise operations, we might think about Bitwise implementation process, ie ~ x = 1111111 ... 1-x , that is, we will convert this into operation * (--1 ) + unsigned Long Long maximum to
Code
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef unsigned long long ll; 4 struct node { 5 int next, to; 6 } e[200010 << 1]; 7 int num, head[200010]; 8 inline void add(int from, int to) { 9 e[++num].next = head[from]; 10 e[num].to = to; 11 head[from] = num; 12 } 13 int top[200010], fa[200010], dep[200010], size[200010], son[200010], dfn[200010], cnt; 14 void dfs1(int now, int f, int d) { 15 dep[now] = d; 16 fa[now] = f; 17 size[now] = 1; 18 for (register int i = head[now]; i; i = e[i].next) 19 if (e[i].to != f) { 20 dfs1(e[i].to, now, d + 1); 21 size[now] += size[e[i].to]; 22 if (size[son[now]] < size[e[i].to]) son[now] = e[i].to; 23 } 24 } 25 void dfs2(int now, int f) { 26 top[now] = f; 27 dfn[now] = ++cnt; 28 if (son[now]) dfs2(son[now], f); 29 for (register int i = head[now]; i; i = e[i].next) 30 if (e[i].to != son[now] && e[i].to != fa[now]) dfs2(e[i].to, e[i].to); 31 } 32 ll sum[200010 << 2]; 33 ll addtag[200010 << 2]; 34 ll addmul[200010 << 2]; 35 int n; 36 void build(int now, int l, int r) { 37 sum[now] = addtag[now] = 0; 38 addmul[now] = 1; 39 if (l == r) return ; 40 int mid = l + r >> 1; 41 build(now << 1, l, mid); 42 build(now << 1 | 1, mid + 1, r); 43 } 44 void pushup(int now) { 45 sum[now] = sum[now << 1] + sum[now << 1 | 1]; 46 } 47 void pushdown(int now, ll l, ll r) { 48 if (addmul[now] != 1) { 49 sum[now << 1] *= addmul[now]; 50 addmul[now << 1] *= addmul[now]; 51 addtag[now << 1] *= addmul[now]; 52 sum[now << 1 | 1] *= addmul[now]; 53 addmul[now << 1 | 1] *= addmul[now]; 54 addtag[now << 1 | 1] *= addmul[now]; 55 addmul[now] = 1; 56 } 57 if (addtag[now]) { 58 sum[now << 1] += addtag[now] * l; 59 addtag[now << 1] += addtag[now]; 60 sum[now << 1 | 1] += addtag[now] * r; 61 addtag[now << 1 | 1] += addtag[now]; 62 addtag[now] = 0; 63 } 64 } 65 void updateadd(int now, int l, int r, int x, int y, ll val) { 66 if (x <= l && r <= y) { 67 sum[now] += val * (r - l + 1); 68 addtag[now] += val; 69 return ; 70 } 71 int mid = l + r >> 1; 72 pushdown(now, mid - l + 1, r - mid); 73 if (x <= mid) updateadd(now << 1, l, mid, x, y, val); 74 if (y > mid) updateadd(now << 1 | 1, mid + 1, r, x, y, val); 75 pushup(now); 76 } 77 void updatemul(int now, int l, int r, int x, int y, ll val) { 78 if (x <= l && r <= y) { 79 sum[now] *= val; 80 addtag[now] *= val; 81 addmul[now] *= val; 82 return ; 83 } 84 int mid = l + r >> 1; 85 pushdown(now, mid - l + 1, r - mid); 86 if (x <= mid) updatemul(now << 1, l, mid, x, y, val); 87 if (y > mid) updatemul(now << 1 | 1, mid + 1, r, x, y, val); 88 pushup(now); 89 } 90 ll query(int now, int l, int r, int x, int y) { 91 if (x <= l && r <= y) return sum[now]; 92 int mid = l + r >> 1; 93 pushdown(now, mid - l + 1, r - mid); 94 ll ret = 0; 95 if (x <= mid) ret += query(now << 1, l, mid, x, y); 96 if (y > mid) ret += query(now << 1 | 1, mid + 1, r, x, y); 97 return ret; 98 } 99 void updateadd(int from, int to, ll val) { 100 while (top[from] != top[to]) { 101 if (dep[top[from]] < dep[top[to]]) swap(from, to); 102 updateadd(1, 1, n, dfn[top[from]], dfn[from], val); 103 from = fa[top[from]]; 104 } 105 if (dep[from] > dep[to]) swap(from, to); 106 updateadd(1, 1, n, dfn[from], dfn[to], val); 107 } 108 void updatemul(int from, int to, ll val) { 109 while (top[from] != top[to]) { 110 if (dep[top[from]] < dep[top[to]]) swap(from, to); 111 updatemul(1, 1, n, dfn[top[from]], dfn[from], val); 112 from = fa[top[from]]; 113 } 114 if (dep[from] > dep[to]) swap(from, to); 115 updatemul(1, 1, n, dfn[from], dfn[to], val); 116 } 117 ll query(int from, int to) { 118 ll ret = 0; 119 while (top[from] != top[to]) { 120 if (dep[top[from]] < dep[top[to]]) swap(from, to); 121 ret += query(1, 1, n, dfn[top[from]], dfn[from]); 122 from = fa[top[from]]; 123 } 124 if (dep[from] > dep[to]) swap(from, to); 125 ret += query(1, 1, n, dfn[from], dfn[to]); 126 return ret; 127 } 128 ll SHLAK = 18446744073709551615; 129 int main() { 130 while (~scanf("%d", &n)) { 131 cnt = 0; num = 0; 132 memset(head, 0, sizeof(head)); 133 memset(son, 0, sizeof(son)); 134 for (register int i = 2; i <= n; ++i) { 135 int x; scanf("%d", &x); 136 add(x, i); add(i, x); 137 } 138 dfs1(1, 0, 0); 139 dfs2(1, 1); 140 build(1, 1, n); 141 int m; 142 scanf("%d", &m); 143 for (register int i = 1; i <= m; ++i) { 144 int op, x, y; 145 ll z; 146 scanf("%d%d%d", &op, &x, &y); 147 if (op == 1) { 148 scanf("%llu", &z); 149 updatemul(x, y, z); 150 } 151 else if (op == 2) { 152 scanf("%llu", &z); 153 updateadd(x, y, z); 154 } 155 else if (op == 3) { 156 updatemul(x, y, -1); 157 updateadd(x, y, SHLAK); 158 } 159 else { 160 printf("%llu\n", query(x, y)); 161 } 162 } 163 } 164 return 0; 165 }