# 洛谷P4719 动态dp

  1 #include <cstdio>
2 #include <algorithm>
3
4 const int N = 100010, INF = 0x3f3f3f3f;
5
6 template <class T> inline void read(T &x) {
7     x = 0;
8     char c = getchar();
9     bool f = 0;
10     while(c < '0' || c > '9') {
11         if(c == '-') {
12             f = 1;
13         }
14         c = getchar();
15     }
16     while(c >= '0' && c <= '9') {
17         x = (x << 3) + (x << 1) + c - 48;
18         c = getchar();
19     }
20     if(f) {
21         x = (~x) + 1;
22     }
23     return;
24 }
25
26 struct Edge {
27     int nex, v;
28 }edge[N << 1]; int tp;
29
30 // 0  0 0
31 // 1  0 1
32 // 2  1 0
33 // 3  1 1
34
35 int top[N], e[N], siz[N], pos[N], id[N], val[N], fa[N], son[N], d[N], num, n, len[N];
36 int f[N][2], seg[N * 4][4], tot, ls[N * 4], rs[N * 4], rt[N];
37
38 inline void add(int x, int y) {
39     tp++;
40     edge[tp].v = y;
41     edge[tp].nex = e[x];
42     e[x] = tp;
43     return;
44 }
45
46 void DFS_1(int x, int f) { // son siz fa d
47     fa[x] = f;
48     d[x] = d[f] + 1;
49     siz[x] = 1;
50     for(int i = e[x]; i; i = edge[i].nex) {
51         int y = edge[i].v;
52         if(y == f) {
53             continue;
54         }
55         DFS_1(y, x);
56         siz[x] += siz[y];
57         if(siz[y] > siz[son[x]]) {
58             son[x] = y;
59         }
60     }
61     return;
62 }
63
64 void DFS_2(int x, int f) { // pos id top
65     top[x] = f;
66     pos[x] = ++num;
67     id[num] = x;
68     len[x] = 1;
69     if(son[x]) {
70         DFS_2(son[x], f);
71         len[x] = len[son[x]] + 1;
72     }
73     for(int i = e[x]; i; i = edge[i].nex) {
74         int y = edge[i].v;
75         if(y == son[x] || y == fa[x]) {
76             continue;
77         }
78         DFS_2(y, y);
79     }
80     return;
81 }
82
83 inline void pushup(int o) {
84     int l = ls[o], r = rs[o];
85     seg[o][0] = std::max(seg[l][0] + seg[r][0], seg[l][0] + seg[r][2]);
86     seg[o][0] = std::max(seg[o][0], seg[l][1] + seg[r][0]);
87
88     seg[o][1] = std::max(seg[l][0] + seg[r][1], seg[l][0] + seg[r][3]);
89     seg[o][1] = std::max(seg[o][1], seg[l][1] + seg[r][1]);
90
91     seg[o][2] = std::max(seg[l][2] + seg[r][0], seg[l][2] + seg[r][2]);
92     seg[o][2] = std::max(seg[o][2], seg[l][3] + seg[r][0]);
93
94     seg[o][3] = std::max(seg[l][2] + seg[r][1], seg[l][2] + seg[r][3]);
95     seg[o][3] = std::max(seg[o][3], seg[l][3] + seg[r][1]);
96     return;
97 }
98
99 inline void build(int l, int r, int &o) {
100     if(!o) {
101         o = ++tot;
102     }
103     if(l == r) {
104         seg[o][0] = f[id[r]][0];
105         seg[o][1] = -INF;
106         seg[o][2] = -INF;
107         seg[o][3] = val[id[r]] + f[id[r]][1];
108         return;
109     }
110     int mid = (l + r) >> 1;
111     build(l, mid, ls[o]);
112     build(mid + 1, r, rs[o]);
113     pushup(o);
114     return;
115 }
116
117 void change(int p, int l, int r, int o) {
118     //printf("change -- : %d %d %d \n", p, l, r);
119     if(l == r) {
120         seg[o][0] = f[id[r]][0];
121         seg[o][1] = -INF;
122         seg[o][2] = -INF;
123         seg[o][3] = val[id[r]] + f[id[r]][1];
124         //printf("%d = %d + %d \n", id[r], val[id[r]], f[id[r]][1]);
125         return;
126     }
127     int mid = (l + r) >> 1;
128     if(p <= mid) {
129         change(p, l, mid, ls[o]);
130     }
131     else {
132         change(p, mid + 1, r, rs[o]);
133     }
134     pushup(o);
135     //printf("%d %d \n", id[l], id[r]);
136     //printf("%d %d %d %d \n", seg[o][0], seg[o][1], seg[o][2], seg[o][3]);
137     return;
138 }
139
140 inline void change(int x, int v) {
141     //printf("change %d %d \n", x, v);
142     val[x] = v;
143     while(x) {
144         int xx = top[x];
145         if(fa[xx]) {
146             int temp = std::max(seg[rt[xx]][0], seg[rt[xx]][1]);
147             f[fa[xx]][1] -= temp;
148             f[fa[xx]][0] -= std::max(std::max(seg[rt[xx]][2], seg[rt[xx]][3]), temp);
149         }
150         //printf("ch %d %d %d \n", x, xx, id[pos[xx] + len[xx] - 1]);
151         change(pos[x], pos[xx], pos[xx] + len[xx] - 1, rt[xx]);
152         if(fa[xx]) {
153             int temp = std::max(seg[rt[xx]][0], seg[rt[xx]][1]);
154             f[fa[xx]][1] += temp;
155             f[fa[xx]][0] += std::max(std::max(seg[rt[xx]][2], seg[rt[xx]][3]), temp);
156         }
157         x = fa[xx];
158     }
159     return;
160 }
161
162 int main() {
163     int m;
165     for(int i = 1; i <= n; i++) {
167     }
168     for(int i = 1, x, y; i < n; i++) {
172     }
173     DFS_1(1, 0);
174     DFS_2(1, 1);
175     for(int i = 1; i <= n; i++) {
176         int x = id[n + 1 - i];
177         if(top[x] == x) {
178             build(pos[x], pos[x] + len[x] - 1, rt[x]);
179             if(fa[x]) {
180                 int temp = std::max(seg[rt[x]][0], seg[rt[x]][1]);
181                 f[fa[x]][1] += temp;
182                 f[fa[x]][0] += std::max(std::max(seg[rt[x]][2], seg[rt[x]][3]), temp);
183             }
184         }
185     }
186
187     for(int i = 1, x, y; i <= m; i++) {
189         change(x, y);
190         int a = std::max(seg[rt[1]][0], seg[rt[1]][1]);
191         int b = std::max(seg[rt[1]][2], seg[rt[1]][3]);
192         printf("%d\n", std::max(a, b));
193     }
194
195     return 0;
196 }
AC代码

  1 #include <cstdio>
2 #include <algorithm>
3 #include <cstring>
4 #include <cmath>
5
6 typedef long long LL;
7 const int N = 100010;
8 const LL INF = 1e17;
9
10 template <class T> inline void read(T &x) {
11     x = 0;
12     char c = getchar();
13     while(c < '0' || c > '9') {
14         c = getchar();
15     }
16     while(c >= '0' && c <= '9') {
17         x = (x << 3) + (x << 1) + c - 48;
18         c = getchar();
19     }
20     return;
21 }
22
23 struct Edge {
24     int nex, v;
25 }edge[N * 2]; int tp;
26
27 LL val[N], f[N * 4][2][2], Val[N][2];
28 int e[N], n, m;
29 int fa[N], top[N], pos[N], id[N], siz[N], son[N], num, d[N], ed[N]; // tree div
30 int tot, ls[N * 4], rs[N * 4], rt[N]; // segment tree
31 char str[3];
32
33 inline void add(int x, int y) {
34     tp++;
35     edge[tp].v = y;
36     edge[tp].nex = e[x];
37     e[x] = tp;
38     return;
39 }
40
41 void DFS_1(int x, int f) { // fa son siz d
42     fa[x] = f;
43     siz[x] = 1;
44     d[x] = d[f] + 1;
45     for(int i = e[x]; i; i = edge[i].nex) {
46         int y = edge[i].v;
47         if(y == f) {
48             continue;
49         }
50         DFS_1(y, x);
51         siz[x] += siz[y];
52         if(siz[y] > siz[son[x]]) {
53             son[x] = y;
54         }
55     }
56     //printf("son %d = %d \n", x, son[x]);
57     //printf("siz %d = %d \n", x, siz[x]);
58     return;
59 }
60
61 void DFS_2(int x, int f) { // top pos id
62     pos[x] = ++num;
63     top[x] = f;
64     id[num] = x;
65     ed[f] = num;
66     //printf("x = %d ed %d = %d \n", x, f, ed[f]);
67     if(son[x]) {
68         DFS_2(son[x], f);
69     }
70     for(int i = e[x]; i; i = edge[i].nex) {
71         int y = edge[i].v;
72         if(y == fa[x] || y == son[x]) {
73             continue;
74         }
75         DFS_2(y, y);
76     }
77     return;
78 }
79
80 inline LL mymin(LL x, LL y) {
81     return x < y ? x : y;
82 }
83
84 inline void exmin(LL &a, LL b) {
85     a > b ? a = b : 0;
86     return;
87 }
88
89 inline void pushup(int o) {
90     int l = ls[o], r = rs[o];
91     f[o][0][0] = INF;
92     exmin(f[o][0][0], f[l][0][1] + f[r][0][0]);
93     exmin(f[o][0][0], f[l][0][1] + f[r][1][0]);
94     exmin(f[o][0][0], f[l][0][0] + f[r][1][0]);
95     f[o][0][1] = INF;
96     exmin(f[o][0][1], f[l][0][1] + f[r][0][1]);
97     exmin(f[o][0][1], f[l][0][1] + f[r][1][1]);
98     exmin(f[o][0][1], f[l][0][0] + f[r][1][1]);
99     f[o][1][0] = INF;
100     exmin(f[o][1][0], f[l][1][1] + f[r][0][0]);
101     exmin(f[o][1][0], f[l][1][1] + f[r][1][0]);
102     exmin(f[o][1][0], f[l][1][0] + f[r][1][0]);
103     f[o][1][1] = INF;
104     exmin(f[o][1][1], f[l][1][1] + f[r][0][1]);
105     exmin(f[o][1][1], f[l][1][1] + f[r][1][1]);
106     exmin(f[o][1][1], f[l][1][0] + f[r][1][1]);
107     return;
108 }
109
110 void build(int l, int r, int &o) {
111     if(!o) {
112         o = ++tot;
113     }
114     if(l == r) {
115         // init
116         int x = id[r];
117         f[o][0][0] = Val[x][0];
118         f[o][0][1] = INF;
119         f[o][1][0] = INF;
120         f[o][1][1] = val[x] + Val[x][1];
121         return;
122     }
123     int mid = (l + r) >> 1;
124     build(l, mid, ls[o]);
125     build(mid + 1, r, rs[o]);
126     pushup(o);
127     return;
128 }
129
130 inline int lca(int x, int y) {
131     while(top[x] != top[y]) {
132         if(d[top[x]] <= d[top[y]]) {
133             y = fa[top[y]];
134         }
135         else {
136             x = fa[top[x]];
137         }
138     }
139     return (d[x] < d[y]) ? x : y;
140 }
141
142 inline bool link(int x, int y) {
143     int z = lca(x, y);
144     return std::abs(d[x] - d[y]) == 1 && (z == x || z == y);
145 }
146
147 inline void change(int p, int v, int l, int r, int o) {
148     //printf("change %d %d %d %d \n", p, v, l, r);
149     if(l == r) {
150         if(v) {
151             f[o][0][0] = INF;
152         }
153         else {
154             f[o][1][1] = INF;
155         }
156         return;
157     }
158     int mid = (l + r) >> 1;
159     if(p <= mid) {
160         change(p, v, l, mid, ls[o]);
161     }
162     else {
163         change(p, v, mid + 1, r, rs[o]);
164     }
165     pushup(o);
166     return;
167 }
168
169 inline void update(int p, int l, int r, int o) {
170     if(l == r) {
171         int x = id[r];
172         f[o][0][0] = Val[x][0];
173         f[o][1][1] = val[x] + Val[x][1];
174         return;
175     }
176     int mid = (l + r) >> 1;
177     if(p <= mid) {
178         update(p, l, mid, ls[o]);
179     }
180     else {
181         update(p, mid + 1, r, rs[o]);
182     }
183     pushup(o);
184     return;
185 }
186
187 inline void change(int x, int a) {
188     int xx = x;
189     while(x) {
190         if(fa[top[x]]) {
191             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
192             Val[fa[top[x]]][0] -= temp;
193             Val[fa[top[x]]][1] -= mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
194         }
195         if(x != xx)
196             update(pos[x], pos[top[x]], ed[top[x]], rt[top[x]]);
197         else
198             change(pos[x], a, pos[top[x]], ed[top[x]], rt[top[x]]);
199         if(fa[top[x]]) {
200             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
201             Val[fa[top[x]]][0] += temp;
202             Val[fa[top[x]]][1] += mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
203         }
204         x = fa[top[x]];
205     }
206     return;
207 }
208
209 inline void recover(int x) {
210     while(x) {
211         if(fa[top[x]]) {
212             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
213             Val[fa[top[x]]][0] -= temp;
214             Val[fa[top[x]]][1] -= mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
215         }
216         update(pos[x], pos[top[x]], ed[top[x]], rt[top[x]]);
217         if(fa[top[x]]) {
218             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
219             Val[fa[top[x]]][0] += temp;
220             Val[fa[top[x]]][1] += mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
221         }
222         x = fa[top[x]];
223     }
224     return;
225 }
226
227 int main() {
228
229     //freopen("in.in", "r", stdin);
230     //freopen("my.out", "w", stdout);
232     scanf("%s", str);
233     for(register int i = 1; i <= n; i++) {
235     }
236     for(register int i = 1, x, y; i < n; i++) {
239     }
240     // prework
241     DFS_1(1, 0);
242     DFS_2(1, 1);
243     // build
244     for(register int a = n; a >= 1; a--) {
245         int x = id[a];
246         if(top[x] == x) {
247             build(pos[x], ed[x], rt[x]);
248             if(fa[x]) {
249                 int father = fa[x];
250                 LL temp = mymin(f[rt[x]][1][0], f[rt[x]][1][1]);
251                 Val[father][0] += temp;
252                 Val[father][1] += mymin(mymin(f[rt[x]][0][0], f[rt[x]][0][1]), temp);
253             }
254         }
255     }
256
257     for(register int i = 1, x, a, y, b; i <= m; i++) {
258         scanf("%d%d%d%d", &x, &a, &y, &b);
259         if(!a && !b && link(x, y)) {
260             puts("-1");
261             continue;
262         }
263         change(x, a);
264         change(y, b);
265         printf("%lld\n", mymin(mymin(f[rt[1]][0][0], f[rt[1]][1][1]), mymin(f[rt[1]][0][1], f[rt[1]][1][0])));
266         recover(x);
267         recover(y);
268     }
269
270     return 0;
271 }
AC代码

posted @ 2019-02-16 20:56  huyufeifei  阅读(...)  评论(...编辑  收藏