[Large stone in 2019, I will have a strong team training match warm-up match 20190802 E]

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 }
AC Code

 

Guess you like

Origin www.cnblogs.com/shl-blog/p/11291129.html