zoukankan      html  css  js  c++  java
  • LOJ#2722 情报中心

    解:有个暴力是枚举两条链然后O(n)判定,可以得到15分。

    还可以优化一下,枚举一条链,然后第二条链直接求两端点树上带权距离。可以做到O(m(n + m)),但是我用的树剖,跟上面那一档没啥区别Orz...

    然后是链的部分,把所有链按照左端点小到大排序,左端点相同的时候按右端点小到大。

    然后从右往左加。用一个树状数组维护前缀最大值。如果一个之前区间的左端点在我们当前区间的右端点内,就有交。

    我们漏了一种情况:一个区间被另一个完全包含。于是新开一个树状数组维护即可。注意到这种情况在第一个树状数组中算出的答案不优,会被取代掉。

    这样就有30分了。

      1 /**
      2  * There is no end though there is a start in space. ---Infinity.
      3  * It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
      4  * Only the person who was wisdom can read the most foolish one from the history.
      5  * The fish that lives in the sea doesn't know the world in the land.
      6  * It also ruins and goes if they have wisdom.
      7  * It is funnier that man exceeds the speed of light than fish start living in the land.
      8  * It can be said that this is an final ultimatum from the god to the people who can fight.
      9  *
     10  * Steins;Gate
     11  */
     12 
     13 #include <bits/stdc++.h>
     14 
     15 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
     16 
     17 typedef long long LL;
     18 const int N = 100010;
     19 const LL INF = 9e18;
     20 
     21 struct Edge {
     22     int nex, v;
     23     LL len;
     24 }edge[N << 1]; int tp;
     25 
     26 struct Node {
     27     int x, y;
     28     LL z, val;
     29     inline bool operator < (const Node &w) const {
     30         if(x != w.x) return x < w.x;
     31         return y < w.y;
     32     }
     33 }node[N];
     34 
     35 int n, e[N], m, fa[N], deep[N];
     36 int num, pos[N], son[N], siz[N], top[N];
     37 LL Sum[N], sum[N << 2], d[N], tag[N << 2];
     38 
     39 inline void add(int x, int y, LL z) {
     40     tp++;
     41     edge[tp].v = y;
     42     edge[tp].len = z;
     43     edge[tp].nex = e[x];
     44     e[x] = tp;
     45     return;
     46 }
     47 
     48 void DFS_1(int x, int f) { /// get fa son siz d deep
     49     fa[x] = f;
     50     deep[x] = deep[f] + 1;
     51     siz[x] = 1;
     52     forson(x, i) {
     53         int y = edge[i].v;
     54         if(y == f) continue;
     55         d[y] = d[x] + edge[i].len;
     56         DFS_1(y, x);
     57         siz[x] += siz[y];
     58         if(siz[y] > siz[son[x]]) {
     59             son[x] = y;
     60         }
     61     }
     62     return;
     63 }
     64 
     65 void DFS_2(int x, int f) { /// get top id pos
     66     pos[x] = ++num;
     67     top[x] = f;
     68     Sum[num] = d[x] - d[fa[x]];
     69     if(son[x]) {
     70         DFS_2(son[x], f);
     71     }
     72     forson(x, i) {
     73         int y = edge[i].v;
     74         if(y == fa[x] || y == son[x]) continue;
     75         DFS_2(y, y);
     76     }
     77     return;
     78 }
     79 
     80 inline int lca(int x, int y) {
     81     while(top[x] != top[y]) {
     82         if(deep[top[x]] > deep[top[y]]) {
     83             x = fa[top[x]];
     84         }
     85         else {
     86             y = fa[top[y]];
     87         }
     88     }
     89     return deep[x] < deep[y] ? x : y;
     90 }
     91 
     92 inline LL dis(int x, int y) {
     93     return d[x] + d[y] - 2 * d[lca(x, y)];
     94 }
     95 
     96 inline void pushdown(int l, int r, int o) {
     97     if(tag[o] != -1) {
     98         if(tag[o] == 0) {
     99             sum[o << 1] = sum[o << 1 | 1] = 0;
    100         }
    101         else {
    102             int mid = (l + r) >> 1;
    103             sum[o << 1] = Sum[mid] - Sum[l - 1];
    104             sum[o << 1 | 1] = Sum[r] - Sum[mid];
    105         }
    106         tag[o << 1] = tag[o << 1 | 1] = tag[o];
    107         tag[o] = -1;
    108     }
    109     return;
    110 }
    111 
    112 void Add(int L, int R, int l, int r, int o) {
    113     if(L <= l && r <= R) {
    114         sum[o] = Sum[r] - Sum[l - 1];
    115         tag[o] = 1;
    116         return;
    117     }
    118     int mid = (l + r) >> 1;
    119     pushdown(l, r, o);
    120     if(L <= mid) Add(L, R, l, mid, o << 1);
    121     if(mid < R) Add(L, R, mid + 1, r, o << 1 | 1);
    122     sum[o] = sum[o << 1] + sum[o << 1 | 1];
    123     return;
    124 }
    125 
    126 LL ask(int L, int R, int l, int r, int o) {
    127     if(L <= l && r <= R) {
    128         return sum[o];
    129     }
    130     int mid = (l + r) >> 1;
    131     pushdown(l, r, o);
    132     LL ans = 0;
    133     if(L <= mid) {
    134         ans += ask(L, R, l, mid, o << 1);
    135     }
    136     if(mid < R) {
    137         ans += ask(L, R, mid + 1, r, o << 1 | 1);
    138     }
    139     return ans;
    140 }
    141 
    142 inline void Add(int x, int y) {
    143     while(top[x] != top[y]) {
    144         if(deep[top[x]] > deep[top[y]]) {
    145             std::swap(x, y);
    146         }
    147         Add(pos[top[y]], pos[y], 1, n, 1);
    148         y = fa[top[y]];
    149     }
    150     if(deep[x] > deep[y]) std::swap(x, y);
    151     if(x != y) Add(pos[x] + 1, pos[y], 1, n, 1);
    152     return;
    153 }
    154 
    155 inline LL ask(int x, int y) {
    156     LL ans = 0;
    157     while(top[x] != top[y]) {
    158         if(deep[top[x]] > deep[top[y]]) {
    159             std::swap(x, y);
    160         }
    161         ans += ask(pos[top[y]], pos[y], 1, n, 1);
    162         y = fa[top[y]];
    163     }
    164     if(deep[x] > deep[y]) std::swap(x, y);
    165     if(x != y) ans += ask(pos[x] + 1, pos[y], 1, n, 1);
    166     return ans;
    167 }
    168 
    169 inline void clear() {
    170     memset(e + 1, 0, n * sizeof(int));
    171     memset(son + 1, 0, n * sizeof(int));
    172     tp = 0;
    173     num = 0;
    174     return;
    175 }
    176 /*
    177 1
    178 5
    179 1 2 1
    180 2 3 3
    181 3 4 3
    182 1 5 9
    183 2
    184 1 5 5
    185 2 3 8
    186 */
    187 
    188 namespace Line {
    189     LL ta[N], ta2[N];
    190     inline LL ask(int i) {
    191         LL ans = -INF;
    192         for(; i; i -= i & (-i)) {
    193             ans = std::max(ans, ta[i]);
    194         }
    195         return ans;
    196     }
    197     inline void Add(int i, LL v) {
    198         for(; i <= n; i += i & (-i)) {
    199             ta[i] = std::max(ta[i], v);
    200         }
    201         return;
    202     }
    203     inline LL ask2(int i) {
    204         LL ans = -INF;
    205         for(; i; i -= i & (-i)) {
    206             ans = std::max(ans, ta2[i]);
    207         }
    208         return ans;
    209     }
    210     inline void Add2(int i, LL v) {
    211         for(; i <= n; i += i & (-i)) {
    212             ta2[i] = std::max(ta2[i], v);
    213         }
    214         return;
    215     }
    216     inline void solve() {
    217         for(int i = 1; i <= n; i++) ta2[i] = ta[i] = -INF;
    218         LL ans = -INF;
    219         std::sort(node + 1, node + m + 1);
    220         for(int i = m; i >= 1; i--) {
    221             LL temp = ask(node[i].y - 1);
    222             if(temp != -INF) {
    223                 ans = std::max(ans, temp + node[i].val - Sum[node[i].y]);
    224             }
    225             temp = ask2(node[i].y);
    226             if(temp != -INF) {
    227                 ans = std::max(ans, temp + node[i].val);
    228             }
    229             Add(node[i].x, node[i].val + Sum[node[i].x]);
    230             Add2(node[i].y, node[i].val + Sum[node[i].x] - Sum[node[i].y]);
    231         }
    232         if(ans == -INF) puts("F");
    233         else {
    234             printf("%lld
    ", ans);
    235         }
    236         clear();
    237         return;
    238     }
    239 }
    240 /*
    241 50
    242 2
    243 1 2 914572059
    244 3
    245 1 2 213930211
    246 1 2 0
    247 2 2 0
    248 */
    249 inline void solve() {
    250 
    251     sum[1] = tag[1] = 0;
    252 
    253     scanf("%d", &n);
    254     LL z;
    255     bool FLAG = 1;
    256     for(int i = 1, x, y; i < n; i++) {
    257         scanf("%d%d%lld", &x, &y, &z);
    258         add(x, y, z);
    259         add(y, x, z);
    260         if(y != x + 1) {
    261             FLAG = 0;
    262         }
    263     }
    264 
    265     DFS_1(1, 0);
    266     DFS_2(1, 1);
    267 
    268     for(int i = 1; i <= n; i++) {
    269         Sum[i] += Sum[i - 1];
    270     }
    271 
    272     scanf("%d", &m);
    273     for(int i = 1; i <= m; i++) {
    274         scanf("%d%d%lld", &node[i].x, &node[i].y, &node[i].z);
    275         if(node[i].x > node[i].y) std::swap(node[i].x, node[i].y);
    276         else if(node[i].x == node[i].y) {
    277             m--;
    278             i--;
    279         }
    280         node[i].val = dis(node[i].x, node[i].y) - node[i].z;
    281         //printf("node %d [%d %d] val = %lld 
    ", i, node[i].x, node[i].y, node[i].val);
    282     }
    283     // solve
    284     if(FLAG) {
    285         Line::solve();
    286         return;
    287     }
    288 
    289     if(m > 300) {
    290         clear();
    291         return;
    292     }
    293 
    294     LL ans = -INF;
    295     for(int i = 1; i < m; i++) {
    296         Add(node[i].x, node[i].y);
    297         for(int j = i + 1; j <= m; j++) {
    298             /// choose i j
    299             LL Val = ask(node[j].x, node[j].y);
    300             //printf("Val = %lld 
    ", Val);
    301             if(Val) {
    302                 ans = std::max(ans, node[i].val + node[j].val - Val);
    303             }
    304         }
    305         tag[1] = sum[1] = 0;
    306     }
    307     if(ans == -INF) {
    308         puts("F");
    309     }
    310     else {
    311         printf("%lld
    ", ans);
    312     }
    313     clear();
    314     return;
    315 }
    316 
    317 int main() {
    318 
    319     int T;
    320     scanf("%d", &T);
    321     while(T--) solve();
    322     return 0;
    323 }
    30分代码

    接下来还有c = 0的部分分:枚举每条边,统计所有过它的链中权值最大的两条更新答案。拿线段树合并实现。

      1 #include <bits/stdc++.h>
      2 
      3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
      4 
      5 typedef long long LL;
      6 const int N = 100010;
      7 const LL INF = 9e18;
      8 
      9 struct Edge {
     10     int nex, v;
     11     LL len;
     12 }edge[N << 1]; int tp;
     13 
     14 struct Node {
     15     int x, y;
     16     LL z, val;
     17     inline bool operator < (const Node &w) const {
     18         if(x != w.x) return x < w.x;
     19         return y < w.y;
     20     }
     21 }node[N];
     22 
     23 int n, e[N], m, fa[N], deep[N];
     24 int num, pos[N], son[N], siz[N], top[N];
     25 LL Sum[N], sum[N << 2], d[N], tag[N << 2];
     26 
     27 inline void add(int x, int y, LL z) {
     28     tp++;
     29     edge[tp].v = y;
     30     edge[tp].len = z;
     31     edge[tp].nex = e[x];
     32     e[x] = tp;
     33     return;
     34 }
     35 
     36 void DFS_1(int x, int f) { /// get fa son siz d deep
     37     fa[x] = f;
     38     deep[x] = deep[f] + 1;
     39     siz[x] = 1;
     40     forson(x, i) {
     41         int y = edge[i].v;
     42         if(y == f) continue;
     43         d[y] = d[x] + edge[i].len;
     44         DFS_1(y, x);
     45         siz[x] += siz[y];
     46         if(siz[y] > siz[son[x]]) {
     47             son[x] = y;
     48         }
     49     }
     50     return;
     51 }
     52 
     53 void DFS_2(int x, int f) { /// get top id pos
     54     pos[x] = ++num;
     55     top[x] = f;
     56     Sum[num] = d[x] - d[fa[x]];
     57     if(son[x]) {
     58         DFS_2(son[x], f);
     59     }
     60     forson(x, i) {
     61         int y = edge[i].v;
     62         if(y == fa[x] || y == son[x]) continue;
     63         DFS_2(y, y);
     64     }
     65     return;
     66 }
     67 
     68 inline int lca(int x, int y) {
     69     while(top[x] != top[y]) {
     70         if(deep[top[x]] > deep[top[y]]) {
     71             x = fa[top[x]];
     72         }
     73         else {
     74             y = fa[top[y]];
     75         }
     76     }
     77     return deep[x] < deep[y] ? x : y;
     78 }
     79 
     80 inline LL dis(int x, int y) {
     81     return d[x] + d[y] - 2 * d[lca(x, y)];
     82 }
     83 
     84 inline void pushdown(int l, int r, int o) {
     85     if(tag[o] != -1) {
     86         if(tag[o] == 0) {
     87             sum[o << 1] = sum[o << 1 | 1] = 0;
     88         }
     89         else {
     90             int mid = (l + r) >> 1;
     91             sum[o << 1] = Sum[mid] - Sum[l - 1];
     92             sum[o << 1 | 1] = Sum[r] - Sum[mid];
     93         }
     94         tag[o << 1] = tag[o << 1 | 1] = tag[o];
     95         tag[o] = -1;
     96     }
     97     return;
     98 }
     99 
    100 void Add(int L, int R, int l, int r, int o) {
    101     if(L <= l && r <= R) {
    102         sum[o] = Sum[r] - Sum[l - 1];
    103         tag[o] = 1;
    104         return;
    105     }
    106     int mid = (l + r) >> 1;
    107     pushdown(l, r, o);
    108     if(L <= mid) Add(L, R, l, mid, o << 1);
    109     if(mid < R) Add(L, R, mid + 1, r, o << 1 | 1);
    110     sum[o] = sum[o << 1] + sum[o << 1 | 1];
    111     return;
    112 }
    113 
    114 LL ask(int L, int R, int l, int r, int o) {
    115     if(L <= l && r <= R) {
    116         return sum[o];
    117     }
    118     int mid = (l + r) >> 1;
    119     pushdown(l, r, o);
    120     LL ans = 0;
    121     if(L <= mid) {
    122         ans += ask(L, R, l, mid, o << 1);
    123     }
    124     if(mid < R) {
    125         ans += ask(L, R, mid + 1, r, o << 1 | 1);
    126     }
    127     return ans;
    128 }
    129 
    130 inline void Add(int x, int y) {
    131     while(top[x] != top[y]) {
    132         if(deep[top[x]] > deep[top[y]]) {
    133             std::swap(x, y);
    134         }
    135         Add(pos[top[y]], pos[y], 1, n, 1);
    136         y = fa[top[y]];
    137     }
    138     if(deep[x] > deep[y]) std::swap(x, y);
    139     if(x != y) Add(pos[x] + 1, pos[y], 1, n, 1);
    140     return;
    141 }
    142 
    143 inline LL ask(int x, int y) {
    144     LL ans = 0;
    145     while(top[x] != top[y]) {
    146         if(deep[top[x]] > deep[top[y]]) {
    147             std::swap(x, y);
    148         }
    149         ans += ask(pos[top[y]], pos[y], 1, n, 1);
    150         y = fa[top[y]];
    151     }
    152     if(deep[x] > deep[y]) std::swap(x, y);
    153     if(x != y) ans += ask(pos[x] + 1, pos[y], 1, n, 1);
    154     return ans;
    155 }
    156 
    157 inline void clear() {
    158     memset(e + 1, 0, n * sizeof(int));
    159     memset(son + 1, 0, n * sizeof(int));
    160     tp = 0;
    161     num = 0;
    162     return;
    163 }
    164 /*
    165 1
    166 5
    167 1 2 1
    168 2 3 3
    169 3 4 3
    170 1 5 9
    171 2
    172 1 5 5
    173 2 3 8
    174 */
    175 
    176 namespace Line {
    177     LL ta[N], ta2[N];
    178     inline LL ask(int i) {
    179         LL ans = -INF;
    180         for(; i; i -= i & (-i)) {
    181             ans = std::max(ans, ta[i]);
    182         }
    183         return ans;
    184     }
    185     inline void Add(int i, LL v) {
    186         for(; i <= n; i += i & (-i)) {
    187             ta[i] = std::max(ta[i], v);
    188         }
    189         return;
    190     }
    191     inline LL ask2(int i) {
    192         LL ans = -INF;
    193         for(; i; i -= i & (-i)) {
    194             ans = std::max(ans, ta2[i]);
    195         }
    196         return ans;
    197     }
    198     inline void Add2(int i, LL v) {
    199         for(; i <= n; i += i & (-i)) {
    200             ta2[i] = std::max(ta2[i], v);
    201         }
    202         return;
    203     }
    204     inline void solve() {
    205         for(int i = 1; i <= n; i++) ta2[i] = ta[i] = -INF;
    206         LL ans = -INF;
    207         std::sort(node + 1, node + m + 1);
    208         for(int i = m; i >= 1; i--) {
    209             LL temp = ask(node[i].y - 1);
    210             if(temp != -INF) {
    211                 ans = std::max(ans, temp + node[i].val - Sum[node[i].y]);
    212             }
    213             temp = ask2(node[i].y);
    214             if(temp != -INF) {
    215                 ans = std::max(ans, temp + node[i].val);
    216             }
    217             Add(node[i].x, node[i].val + Sum[node[i].x]);
    218             Add2(node[i].y, node[i].val + Sum[node[i].x] - Sum[node[i].y]);
    219         }
    220         if(ans == -INF) puts("F");
    221         else {
    222             printf("%lld
    ", ans);
    223         }
    224         return;
    225     }
    226 }
    227 
    228 namespace C0 {
    229     int rt[N], xx;
    230     LL Ans, X[N];
    231     std::vector<int> v[N];
    232     namespace seg {
    233         const int M = 20000010;
    234         int ls[M], rs[M], tot, cnt[M];
    235         LL sum[M];
    236         void insert(int p, int v, int l, int r, int &o) {
    237             if(!o) {
    238                 o = ++tot;
    239                 sum[o] = cnt[o] = ls[o] = rs[o] = 0;
    240             }
    241             if(l == r) {
    242                 sum[o] += v * X[r];
    243                 cnt[o] += v;
    244                 return;
    245             }
    246             int mid = (l + r) >> 1;
    247             if(p <= mid) {
    248                 insert(p, v, l, mid, ls[o]);
    249             }
    250             else {
    251                 insert(p, v, mid + 1, r, rs[o]);
    252             }
    253             sum[o] = sum[ls[o]] + sum[rs[o]];
    254             cnt[o] = cnt[ls[o]] + cnt[rs[o]];
    255             return;
    256         }
    257         LL ask(int k, int l, int r, int o) {
    258             if(l == r) {
    259                 return k * X[r];
    260             }
    261             int mid = (l + r) >> 1;
    262             if(k <= cnt[rs[o]]) {
    263                 return ask(k, mid + 1, r, rs[o]);
    264             }
    265             else {
    266                 return ask(k - cnt[rs[o]], l, mid, ls[o]) + sum[rs[o]];
    267             }
    268         }
    269         inline LL Ask(int x) {
    270             if(cnt[rt[x]] < 2) return -INF;
    271             return ask(2, 1, xx, rt[x]);
    272         }
    273         int merge(int x, int y) {
    274             if(!x || !y) return x | y;
    275             sum[x] += sum[y];
    276             cnt[x] += cnt[y];
    277             ls[x] = merge(ls[x], ls[y]);
    278             rs[x] = merge(rs[x], rs[y]);
    279             return x;
    280         }
    281         inline void Merge(int x, int y) {
    282             rt[x] = merge(rt[x], rt[y]);
    283             return;
    284         }
    285     }
    286     void DFS(int x, int f) {
    287         forson(x, i) {
    288             int y = edge[i].v;
    289             if(y == f) continue;
    290             DFS(y, x);
    291             Ans = std::max(Ans, seg::Ask(y));
    292             seg::Merge(x, y);
    293         }
    294         for(int i = 0; i < (int)v[x].size(); i++) {
    295             int t = v[x][i];
    296             if(t > 0) {
    297                 seg::insert(t, 1, 1, xx, rt[x]);
    298             }
    299             else {
    300                 seg::insert(-t, -1, 1, xx, rt[x]);
    301             }
    302         }
    303         return;
    304     }
    305     inline void solve() {
    306         memset(rt + 1, 0, n * sizeof(int));
    307         seg::tot = 0;
    308         Ans = -INF;
    309         for(int i = 1; i <= n; i++) v[i].clear();
    310         for(int i = 1; i <= m; i++) {
    311             X[i] = node[i].val;
    312         }
    313         std::sort(X + 1, X + m + 1);
    314         xx = std::unique(X + 1, X + m + 1) - X - 1;
    315         for(int i = 1; i <= m; i++) {
    316             int val = std::lower_bound(X + 1, X + xx + 1, node[i].val) - X;
    317             int x = node[i].x, y = node[i].y, z = lca(node[i].x, node[i].y);
    318             v[x].push_back(val);
    319             v[y].push_back(val);
    320             v[z].push_back(-val);
    321             v[z].push_back(-val);
    322         }
    323         DFS(1, 0);
    324         if(Ans == -INF) puts("F");
    325         else printf("%lld
    ", Ans);
    326         return;
    327     }
    328 }
    329 
    330 /*
    331 50
    332 2
    333 1 2 914572059
    334 3
    335 1 2 213930211
    336 1 2 0
    337 2 2 0
    338 */
    339 inline void solve() {
    340 
    341     sum[1] = tag[1] = 0;
    342 
    343     scanf("%d", &n);
    344     LL z;
    345     bool FLAG = 1, c0 = 1;
    346     for(int i = 1, x, y; i < n; i++) {
    347         scanf("%d%d%lld", &x, &y, &z);
    348         add(x, y, z);
    349         add(y, x, z);
    350         if(z) c0 = 0;
    351         if(y != x + 1) {
    352             FLAG = 0;
    353         }
    354     }
    355 
    356     DFS_1(1, 0);
    357     DFS_2(1, 1);
    358 
    359     for(int i = 1; i <= n; i++) {
    360         Sum[i] += Sum[i - 1];
    361     }
    362 
    363     scanf("%d", &m);
    364     for(int i = 1; i <= m; i++) {
    365         scanf("%d%d%lld", &node[i].x, &node[i].y, &node[i].z);
    366         if(node[i].x > node[i].y) std::swap(node[i].x, node[i].y);
    367         else if(node[i].x == node[i].y) {
    368             m--;
    369             i--;
    370         }
    371         node[i].val = dis(node[i].x, node[i].y) - node[i].z;
    372         //printf("node %d [%d %d] val = %lld 
    ", i, node[i].x, node[i].y, node[i].val);
    373     }
    374     // solve
    375     if(FLAG) {
    376         Line::solve();
    377         clear();
    378         return;
    379     }
    380     if(c0) {
    381         C0::solve();
    382         clear();
    383         return;
    384     }
    385 
    386     if(m > 300) {
    387         clear();
    388         return;
    389     }
    390 
    391     LL ans = -INF;
    392     for(int i = 1; i < m; i++) {
    393         Add(node[i].x, node[i].y);
    394         for(int j = i + 1; j <= m; j++) {
    395             /// choose i j
    396             LL Val = ask(node[j].x, node[j].y);
    397             //printf("Val = %lld 
    ", Val);
    398             if(Val) {
    399                 ans = std::max(ans, node[i].val + node[j].val - Val);
    400             }
    401         }
    402         tag[1] = sum[1] = 0;
    403     }
    404     if(ans == -INF) {
    405         puts("F");
    406     }
    407     else {
    408         printf("%lld
    ", ans);
    409     }
    410     clear();
    411     return;
    412 }
    413 
    414 int main() {
    415 
    416     int T;
    417     scanf("%d", &T);
    418     while(T--) solve();
    419     return 0;
    420 }
    45分代码

    接下来是这个东西...

    然而我只得到了20分...可能比较丑。

    只枚举有公共部分的链:考虑枚举每条边,并m2枚举经过这条边的链。

    这样两条链可能会在多条边上算多次,于是我们限定某一个链的lca是这条边的上端点。

    具体一点,线段树合并搞出经过每条边的链,然后枚举以这条边为lca的链,预处理树上距离。然后枚举经过这条边的所有链,并更新答案。

    其实可以O(1)lca和长链剖分O(1)k级祖先来优化,但是我已经写不动啦......

      1 /**
      2  * There is no end though there is a start in space. ---Infinity.
      3  * It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
      4  * Only the person who was wisdom can read the most foolish one from the history.
      5  * The fish that lives in the sea doesn't know the world in the land.
      6  * It also ruins and goes if they have wisdom.
      7  * It is funnier that man exceeds the speed of light than fish start living in the land.
      8  * It can be said that this is an final ultimatum from the god to the people who can fight.
      9  *
     10  * Steins;Gate
     11  */
     12 
     13 #include <bits/stdc++.h>
     14 
     15 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
     16 
     17 typedef long long LL;
     18 const int N = 100010, M = 20000010;
     19 const LL INF = 9e18;
     20 
     21 struct Edge {
     22     int nex, v;
     23     LL len;
     24     bool vis;
     25 }edge[N << 1]; int tp = 1;
     26 
     27 struct Node {
     28     int x, y;
     29     LL z, val;
     30     inline bool operator < (const Node &w) const {
     31         if(x != w.x) return x < w.x;
     32         return y < w.y;
     33     }
     34 }node[N];
     35 
     36 int n, e[N], m, fa[N], deep[N], ls[M], rs[M], tot;
     37 int num, pos[N], son[N], siz[N], top[N], rt[N], pw[N];
     38 LL Sum[N], sum[N << 2], d[N], tag[N << 2];
     39 
     40 inline void add(int x, int y, LL z) {
     41     tp++;
     42     edge[tp].v = y;
     43     edge[tp].len = z;
     44     edge[tp].vis = 0;
     45     edge[tp].nex = e[x];
     46     e[x] = tp;
     47     return;
     48 }
     49 
     50 void DFS_1(int x, int f) { /// get fa son siz d deep
     51     fa[x] = f;
     52     deep[x] = deep[f] + 1;
     53     siz[x] = 1;
     54     forson(x, i) {
     55         int y = edge[i].v;
     56         if(y == f) continue;
     57         d[y] = d[x] + edge[i].len;
     58         DFS_1(y, x);
     59         siz[x] += siz[y];
     60         if(siz[y] > siz[son[x]]) {
     61             son[x] = y;
     62         }
     63     }
     64     return;
     65 }
     66 
     67 void DFS_2(int x, int f) { /// get top id pos
     68     pos[x] = ++num;
     69     top[x] = f;
     70     Sum[num] = d[x] - d[fa[x]];
     71     if(son[x]) {
     72         DFS_2(son[x], f);
     73     }
     74     forson(x, i) {
     75         int y = edge[i].v;
     76         if(y == fa[x] || y == son[x]) continue;
     77         DFS_2(y, y);
     78     }
     79     return;
     80 }
     81 
     82 inline int lca(int x, int y) {
     83     while(top[x] != top[y]) {
     84         if(deep[top[x]] > deep[top[y]]) {
     85             x = fa[top[x]];
     86         }
     87         else {
     88             y = fa[top[y]];
     89         }
     90     }
     91     return deep[x] < deep[y] ? x : y;
     92 }
     93 
     94 inline LL dis(int x, int y) {
     95     return d[x] + d[y] - 2 * d[lca(x, y)];
     96 }
     97 
     98 inline void pushdown(int l, int r, int o) {
     99     if(tag[o] != -1) {
    100         if(tag[o] == 0) {
    101             sum[o << 1] = sum[o << 1 | 1] = 0;
    102         }
    103         else {
    104             int mid = (l + r) >> 1;
    105             sum[o << 1] = Sum[mid] - Sum[l - 1];
    106             sum[o << 1 | 1] = Sum[r] - Sum[mid];
    107         }
    108         tag[o << 1] = tag[o << 1 | 1] = tag[o];
    109         tag[o] = -1;
    110     }
    111     return;
    112 }
    113 
    114 void Add(int L, int R, int l, int r, int o) {
    115     if(L <= l && r <= R) {
    116         sum[o] = Sum[r] - Sum[l - 1];
    117         tag[o] = 1;
    118         return;
    119     }
    120     int mid = (l + r) >> 1;
    121     pushdown(l, r, o);
    122     if(L <= mid) Add(L, R, l, mid, o << 1);
    123     if(mid < R) Add(L, R, mid + 1, r, o << 1 | 1);
    124     sum[o] = sum[o << 1] + sum[o << 1 | 1];
    125     return;
    126 }
    127 
    128 LL ask(int L, int R, int l, int r, int o) {
    129     if(L <= l && r <= R) {
    130         return sum[o];
    131     }
    132     int mid = (l + r) >> 1;
    133     pushdown(l, r, o);
    134     LL ans = 0;
    135     if(L <= mid) {
    136         ans += ask(L, R, l, mid, o << 1);
    137     }
    138     if(mid < R) {
    139         ans += ask(L, R, mid + 1, r, o << 1 | 1);
    140     }
    141     return ans;
    142 }
    143 
    144 inline void Add(int x, int y) {
    145     while(top[x] != top[y]) {
    146         if(deep[top[x]] > deep[top[y]]) {
    147             std::swap(x, y);
    148         }
    149         Add(pos[top[y]], pos[y], 1, n, 1);
    150         y = fa[top[y]];
    151     }
    152     if(deep[x] > deep[y]) std::swap(x, y);
    153     if(x != y) Add(pos[x] + 1, pos[y], 1, n, 1);
    154     return;
    155 }
    156 
    157 inline LL ask(int x, int y) {
    158     LL ans = 0;
    159     while(top[x] != top[y]) {
    160         if(deep[top[x]] > deep[top[y]]) {
    161             std::swap(x, y);
    162         }
    163         ans += ask(pos[top[y]], pos[y], 1, n, 1);
    164         y = fa[top[y]];
    165     }
    166     if(deep[x] > deep[y]) std::swap(x, y);
    167     if(x != y) ans += ask(pos[x] + 1, pos[y], 1, n, 1);
    168     return ans;
    169 }
    170 
    171 inline void clear() {
    172     memset(e + 1, 0, n * sizeof(int));
    173     memset(son + 1, 0, n * sizeof(int));
    174     tp = 1;
    175     num = 0;
    176     return;
    177 }
    178 /*
    179 1
    180 5
    181 1 2 1
    182 2 3 3
    183 3 4 3
    184 1 5 9
    185 2
    186 1 5 5
    187 2 3 8
    188 */
    189 
    190 namespace Line {
    191     LL ta[N], ta2[N];
    192     inline LL ask(int i) {
    193         LL ans = -INF;
    194         for(; i; i -= i & (-i)) {
    195             ans = std::max(ans, ta[i]);
    196         }
    197         return ans;
    198     }
    199     inline void Add(int i, LL v) {
    200         for(; i <= n; i += i & (-i)) {
    201             ta[i] = std::max(ta[i], v);
    202         }
    203         return;
    204     }
    205     inline LL ask2(int i) {
    206         LL ans = -INF;
    207         for(; i; i -= i & (-i)) {
    208             ans = std::max(ans, ta2[i]);
    209         }
    210         return ans;
    211     }
    212     inline void Add2(int i, LL v) {
    213         for(; i <= n; i += i & (-i)) {
    214             ta2[i] = std::max(ta2[i], v);
    215         }
    216         return;
    217     }
    218     inline void solve() {
    219         for(int i = 1; i <= n; i++) ta2[i] = ta[i] = -INF;
    220         LL ans = -INF;
    221         std::sort(node + 1, node + m + 1);
    222         for(int i = m; i >= 1; i--) {
    223             LL temp = ask(node[i].y - 1);
    224             if(temp != -INF) {
    225                 ans = std::max(ans, temp + node[i].val - Sum[node[i].y]);
    226             }
    227             temp = ask2(node[i].y);
    228             if(temp != -INF) {
    229                 ans = std::max(ans, temp + node[i].val);
    230             }
    231             Add(node[i].x, node[i].val + Sum[node[i].x]);
    232             Add2(node[i].y, node[i].val + Sum[node[i].x] - Sum[node[i].y]);
    233         }
    234         if(ans == -INF) puts("F");
    235         else {
    236             printf("%lld
    ", ans);
    237         }
    238         return;
    239     }
    240 }
    241 
    242 namespace C0 {
    243     int xx;
    244     LL Ans, X[N];
    245     std::vector<int> v[N];
    246     namespace seg {
    247         int cnt[M];
    248         LL sum[M];
    249         void insert(int p, int v, int l, int r, int &o) {
    250             if(!o) {
    251                 o = ++tot;
    252                 sum[o] = cnt[o] = ls[o] = rs[o] = 0;
    253             }
    254             if(l == r) {
    255                 sum[o] += v * X[r];
    256                 cnt[o] += v;
    257                 return;
    258             }
    259             int mid = (l + r) >> 1;
    260             if(p <= mid) {
    261                 insert(p, v, l, mid, ls[o]);
    262             }
    263             else {
    264                 insert(p, v, mid + 1, r, rs[o]);
    265             }
    266             sum[o] = sum[ls[o]] + sum[rs[o]];
    267             cnt[o] = cnt[ls[o]] + cnt[rs[o]];
    268             return;
    269         }
    270         LL ask(int k, int l, int r, int o) {
    271             if(l == r) {
    272                 return k * X[r];
    273             }
    274             int mid = (l + r) >> 1;
    275             if(k <= cnt[rs[o]]) {
    276                 return ask(k, mid + 1, r, rs[o]);
    277             }
    278             else {
    279                 return ask(k - cnt[rs[o]], l, mid, ls[o]) + sum[rs[o]];
    280             }
    281         }
    282         inline LL Ask(int x) {
    283             if(cnt[rt[x]] < 2) return -INF;
    284             return ask(2, 1, xx, rt[x]);
    285         }
    286         int merge(int x, int y) {
    287             if(!x || !y) return x | y;
    288             sum[x] += sum[y];
    289             cnt[x] += cnt[y];
    290             ls[x] = merge(ls[x], ls[y]);
    291             rs[x] = merge(rs[x], rs[y]);
    292             return x;
    293         }
    294         inline void Merge(int x, int y) {
    295             rt[x] = merge(rt[x], rt[y]);
    296             return;
    297         }
    298     }
    299     void DFS(int x, int f) {
    300         forson(x, i) {
    301             int y = edge[i].v;
    302             if(y == f) continue;
    303             DFS(y, x);
    304             Ans = std::max(Ans, seg::Ask(y));
    305             seg::Merge(x, y);
    306         }
    307         for(int i = 0; i < (int)v[x].size(); i++) {
    308             int t = v[x][i];
    309             if(t > 0) {
    310                 seg::insert(t, 1, 1, xx, rt[x]);
    311             }
    312             else {
    313                 seg::insert(-t, -1, 1, xx, rt[x]);
    314             }
    315         }
    316         return;
    317     }
    318     inline void solve() {
    319         memset(rt + 1, 0, n * sizeof(int));
    320         tot = 0;
    321         Ans = -INF;
    322         for(int i = 1; i <= n; i++) v[i].clear();
    323         for(int i = 1; i <= m; i++) {
    324             X[i] = node[i].val;
    325         }
    326         std::sort(X + 1, X + m + 1);
    327         xx = std::unique(X + 1, X + m + 1) - X - 1;
    328         for(int i = 1; i <= m; i++) {
    329             int val = std::lower_bound(X + 1, X + xx + 1, node[i].val) - X;
    330             int x = node[i].x, y = node[i].y, z = lca(node[i].x, node[i].y);
    331             v[x].push_back(val);
    332             v[y].push_back(val);
    333             v[z].push_back(-val);
    334             v[z].push_back(-val);
    335         }
    336         DFS(1, 0);
    337         if(Ans == -INF) puts("F");
    338         else printf("%lld
    ", Ans);
    339         return;
    340     }
    341 }
    342 
    343 namespace tbf {
    344     LL d2[N], Ans;
    345     int Top, stk[N], stk2[N], Top2, faa[N][20];
    346     std::vector<int> vx[N], v[N];
    347     LL dis2(int x, int y) {
    348         return d2[x] + d2[y] - 2 * d2[lca(x, y)];
    349     }
    350     void DFS_3(int x, int f) { /// get dis2
    351         forson(x, i) {
    352             int y = edge[i].v;
    353             if(y == f) continue;
    354             d2[y] = d2[x] + edge[i].len * edge[i].vis;
    355             DFS_3(y, x);
    356         }
    357         return;
    358     }
    359     bool DFS_4(int x, int f, int t) { /// visit a link
    360         if(x == t) {
    361             Top = 0;
    362             return true;
    363         }
    364         forson(x, i) {
    365             int y = edge[i].v;
    366             if(y == f) {
    367                 continue;
    368             }
    369             if(DFS_4(y, x, t)) {
    370                 edge[i].vis = edge[i ^ 1].vis = 1;
    371                 stk[++Top] = i;
    372                 return true;
    373             }
    374         }
    375         return false;
    376     }
    377     namespace seg {
    378         int sum[M];
    379         void insert(int p, int v, int l, int r, int &o) {
    380             if(!o) {
    381                 o = ++tot;
    382                 ls[o] = rs[o] = sum[o] = 0;
    383             }
    384             if(l == r) {
    385                 sum[o] += v;
    386                 return;
    387             }
    388             int mid = (l + r) >> 1;
    389             if(p <= mid) insert(p, v, l, mid, ls[o]);
    390             else insert(p, v, mid + 1, r, rs[o]);
    391             sum[o] = sum[ls[o]] + sum[rs[o]];
    392             return;
    393         }
    394         void solve(int l, int r, int o) {
    395             if(l == r) {
    396                 stk2[++Top2] = r;
    397                 return;
    398             }
    399             int mid = (l + r) >> 1;
    400             if(sum[ls[o]]) {
    401                 solve(l, mid, ls[o]);
    402             }
    403             if(sum[rs[o]]) {
    404                 solve(mid + 1, r, rs[o]);
    405             }
    406             return;
    407         }
    408         int merge(int x, int y) {
    409             if(!x || !y) return x | y;
    410             sum[x] += sum[y];
    411             ls[x] = merge(ls[x], ls[y]);
    412             rs[x] = merge(rs[x], rs[y]);
    413             return x;
    414         }
    415     }
    416 
    417     void DFS_5(int x, int f) {
    418         forson(x, i) {
    419             int y = edge[i].v;
    420             if(y == f) continue;
    421             DFS_5(y, x);
    422             Top2 = 0;
    423             seg::solve(1, m, rt[y]);
    424             for(int j = 0; j < (int)vx[y].size(); j++) {
    425                 int z = vx[y][j];
    426                 /// link z
    427                 DFS_4(node[z].x, 0, node[z].y);
    428                 DFS_3(1, 0);
    429                 for(int k = 1; k <= Top2; k++) {
    430                     int w = stk2[k]; /// link w
    431                     if(w == z) continue;
    432                     Ans = std::max(Ans, node[z].val + node[w].val - dis2(node[w].x, node[w].y));
    433                 }
    434                 while(Top) {
    435                     edge[stk[Top]].vis = edge[stk[Top] ^ 1].vis = 0;
    436                     Top--;
    437                 }
    438             }
    439             rt[x] = seg::merge(rt[x], rt[y]);
    440         }
    441         /// insert
    442         for(int i = 0; i < (int)v[x].size(); i++) {
    443             int t = v[x][i];
    444             if(t > 0) {
    445                 seg::insert(t, 1, 1, m, rt[x]);
    446             }
    447             else {
    448                 seg::insert(-t, -1, 1, m, rt[x]);
    449             }
    450         }
    451         return;
    452     }
    453     void DFS_6(int x, int f) {
    454         faa[x][0] = f;
    455         forson(x, i) {
    456             int y = edge[i].v;
    457             if(y == f) continue;
    458             DFS_6(y, x);
    459         }
    460         return;
    461     }
    462     inline void prework() {
    463         for(int j = 1; j <= pw[n]; j++) {
    464             for(int i = 1; i <= n; i++) {
    465                 faa[i][j] = faa[faa[i][j - 1]][j - 1];
    466             }
    467         }
    468         return;
    469     }
    470     inline int Find(int x, int z) {
    471         int t = pw[n];
    472         while(t >= 0 && fa[x] != z) {
    473             if(deep[faa[x][t]] > deep[z]) {
    474                 x = faa[x][t];
    475             }
    476             t--;
    477         }
    478         return x;
    479     }
    480     inline void solve() {
    481         tot = 0;
    482         Ans = -INF;
    483         memset(rt + 1, 0, n * sizeof(int));
    484         for(int i = 1; i <= n; i++) {
    485             v[i].clear();
    486             vx[i].clear();
    487         }
    488         DFS_6(1, 0);
    489         prework();
    490         for(int i = 1; i <= m; i++) {
    491             int x = node[i].x, y = node[i].y, z = lca(x, y);
    492             v[x].push_back(i);
    493             v[y].push_back(i);
    494             v[z].push_back(-i);
    495             v[z].push_back(-i);
    496             if(x != z) {
    497                 int xx = Find(x, z);
    498                 vx[xx].push_back(i);
    499             }
    500             if(y != z) {
    501                 int yy = Find(y, z);
    502                 vx[yy].push_back(i);
    503             }
    504         }
    505         DFS_5(1, 0);
    506         if(Ans == -INF) puts("F");
    507         else printf("%lld
    ", Ans);
    508         return;
    509     }
    510 } /** namespace tbf */
    511 
    512 inline void solve() {
    513 
    514     sum[1] = tag[1] = 0;
    515 
    516     scanf("%d", &n);
    517     LL z;
    518     bool FLAG = 1, c0 = 1;
    519     for(int i = 1, x, y; i < n; i++) {
    520         scanf("%d%d%lld", &x, &y, &z);
    521         add(x, y, z);
    522         add(y, x, z);
    523         if(z) c0 = 0;
    524         if(y != x + 1) {
    525             FLAG = 0;
    526         }
    527     }
    528 
    529     DFS_1(1, 0);
    530     DFS_2(1, 1);
    531 
    532     for(int i = 1; i <= n; i++) {
    533         Sum[i] += Sum[i - 1];
    534     }
    535 
    536     scanf("%d", &m);
    537     for(int i = 1; i <= m; i++) {
    538         scanf("%d%d%lld", &node[i].x, &node[i].y, &node[i].z);
    539         if(node[i].x > node[i].y) std::swap(node[i].x, node[i].y);
    540         else if(node[i].x == node[i].y) {
    541             m--;
    542             i--;
    543         }
    544         node[i].val = dis(node[i].x, node[i].y) - node[i].z;
    545         //printf("node %d [%d %d] val = %lld 
    ", i, node[i].x, node[i].y, node[i].val);
    546     }
    547     // solve
    548 
    549     tbf::solve();
    550     clear();
    551     return;
    552 
    553     if(FLAG) {
    554         Line::solve();
    555         clear();
    556         return;
    557     }
    558     if(c0) {
    559         C0::solve();
    560         clear();
    561         return;
    562     }
    563 
    564     if(m > 300) {
    565         tbf::solve();
    566         clear();
    567         return;
    568     }
    569 
    570     LL ans = -INF;
    571     for(int i = 1; i < m; i++) {
    572         Add(node[i].x, node[i].y);
    573         for(int j = i + 1; j <= m; j++) {
    574             /// choose i j
    575             LL Val = ask(node[j].x, node[j].y);
    576             //printf("Val = %lld 
    ", Val);
    577             if(Val) {
    578                 ans = std::max(ans, node[i].val + node[j].val - Val);
    579             }
    580         }
    581         tag[1] = sum[1] = 0;
    582     }
    583     if(ans == -INF) {
    584         puts("F");
    585     }
    586     else {
    587         printf("%lld
    ", ans);
    588     }
    589     clear();
    590     return;
    591 }
    592 
    593 int main() {
    594 
    595     for(int i = 2; i < N; i++) pw[i] = pw[i >> 1] + 1;
    596 
    597     int T;
    598     scanf("%d", &T);
    599     while(T--) solve();
    600     return 0;
    601 }
    20分真暴力代码

    接下来是S1的部分分:所有lca全部不同。

    实际上(参考yww的代码)我们要维护两个东西,一个是val最大值,一个是val + d[lca]的最大值。然后更新的时候,把线段树交错更新。

    也就是说左儿子(较浅)的val + 右儿子(较深)的(val + d[lca])然后减去红点的深度。

    然后我们要在插入和merge的同时更新。注意到我们还有一个删除操作,x子树搞完之后,深度大于等于x的全部失效,也就是我们要把线段树右边的一段全部清除。

    DFS那里插入删除merge的顺序非常重要....反正我试了很久才搞对顺序。

      1 #include <bits/stdc++.h>
      2 
      3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
      4 
      5 typedef long long LL;
      6 const int N = 100010;
      7 const LL INF = 4e18;
      8 
      9 struct Edge {
     10     int nex, v;
     11     LL len;
     12 }edge[N << 1]; int tp = 1;
     13 
     14 struct Node {
     15     int x, y, w;
     16     LL val, z;
     17 }node[N];
     18 
     19 int e[N], num2, pos2[N], ST[N][20], pw[N], deep[N], n, m, fa[N];
     20 LL d[N];
     21 std::bitset<N> visLca;
     22 
     23 inline void add(int x, int y, LL z) {
     24     tp++;
     25     edge[tp].v = y;
     26     edge[tp].len = z;
     27     edge[tp].nex = e[x];
     28     e[x] = tp;
     29     return;
     30 }
     31 
     32 inline void clear() {
     33     memset(e + 1, 0, n * sizeof(int));
     34     visLca.reset();
     35     tp = 1;
     36     num2 = 0;
     37     return;
     38 }
     39 
     40 void DFS(int x, int f) {
     41     pos2[x] = ++num2;
     42     ST[num2][0] = x;
     43     deep[x] = deep[f] + 1;
     44     fa[x] = f;
     45     forson(x, i) {
     46         int y = edge[i].v;
     47         if(y == f) {
     48             continue;
     49         }
     50         d[y] = d[x] + edge[i].len;
     51         DFS(y, x);
     52         ST[++num2][0] = x;
     53     }
     54     return;
     55 }
     56 
     57 inline void prework() {
     58     for(int j = 1; j <= pw[num2]; j++) {
     59         for(int i = 1; i + (1 << j) - 1 <= num2; i++) {
     60             if(deep[ST[i][j - 1]] < deep[ST[i + (1 << (j - 1))][j - 1]]) {
     61                 ST[i][j] = ST[i][j - 1];
     62             }
     63             else {
     64                 ST[i][j] = ST[i + (1 << (j - 1))][j - 1];
     65             }
     66         }
     67     }
     68     return;
     69 }
     70 
     71 inline int lca(int x, int y) {
     72     x = pos2[x];
     73     y = pos2[y];
     74     if(x > y) std::swap(x, y);
     75     int t = pw[y - x + 1];
     76     if(deep[ST[x][t]] < deep[ST[y - (1 << t) + 1][t]]) {
     77         return ST[x][t];
     78     }
     79     else {
     80         return ST[y - (1 << t) + 1][t];
     81     }
     82 }
     83 
     84 inline LL dis(int x, int y) {
     85     return d[x] + d[y] - 2 * d[lca(x, y)];
     86 }
     87 
     88 namespace Sone { /// lca != lca
     89     LL Ans;
     90     int rt[N];
     91     std::vector<int> v[N];
     92     namespace seg {
     93         const int M = 10000010;
     94 
     95         int ls[M], rs[M], tot;
     96         LL large[M], largeD[M];
     97 
     98         inline void pushup(int o) {
     99             large[o] = std::max(large[ls[o]], large[rs[o]]);
    100             largeD[o] = std::max(largeD[ls[o]], largeD[rs[o]]);
    101             return;
    102         }
    103         void insert(int p, LL v, LL v2, LL v3, int l, int r, int &o) {
    104             if(!o) {
    105                 o = ++tot;
    106                 ls[o] = rs[o] = 0;
    107                 large[o] = largeD[o] = -INF;
    108             }
    109             if(l == r) {
    110                 large[o] = std::max(large[o], v);
    111                 largeD[o] = std::max(largeD[o], v + v2);
    112                 return;
    113             }
    114             int mid = (l + r) >> 1;
    115             if(p <= mid) {
    116                 Ans = std::max(Ans, largeD[rs[o]] + v - v3);
    117                 insert(p, v, v2, v3, l, mid, ls[o]);
    118             }
    119             else {
    120                 Ans = std::max(Ans, large[ls[o]] + v + v2 - v3);
    121                 insert(p, v, v2, v3, mid + 1, r, rs[o]);
    122             }
    123             pushup(o);
    124             return;
    125         }
    126         int merge(int x, int y, LL v) {
    127             //printf("merge x = %d y = %d v = %lld 
    ", x, y, v);
    128             if(!x || !y) return x | y;
    129             Ans = std::max(Ans, std::max(large[ls[x]] + largeD[rs[y]], large[ls[y]] + largeD[rs[x]]) - v);
    130             large[x] = std::max(large[x], large[y]);
    131             largeD[x] = std::max(largeD[x], largeD[y]);
    132             ls[x] = merge(ls[x], ls[y], v);
    133             rs[x] = merge(rs[x], rs[y], v);
    134             return x;
    135         }
    136         void del(int p, int l, int r, int o) {
    137             if(!o) {
    138                 return;
    139             }
    140             if(l == r) {
    141                 large[o] = largeD[o] = -INF;
    142                 return;
    143             }
    144             int mid = (l + r) >> 1;
    145             if(p <= mid) {
    146                 large[rs[o]] = largeD[rs[o]] = -INF;
    147                 del(p, l, mid, ls[o]);
    148             }
    149             else {
    150                 del(p, mid + 1, r, rs[o]);
    151             }
    152             pushup(o);
    153             return;
    154         }
    155     }
    156 
    157     void DFS_1(int x, int f) {
    158         //printf("x = %d 
    ", x);
    159         for(int i = 0; i < (int)v[x].size(); i++) {
    160             int t = v[x][i];
    161             //printf("x = %d insert p = %d w = %d  v1 = %lld  v2 = %lld 
    ", x, deep[node[t].w], node[t].w, node[t].val, d[node[t].w]);
    162             seg::insert(deep[node[t].w], node[t].val, d[node[t].w], d[x], 1, n, rt[x]);
    163         }
    164         forson(x, i) {
    165             int y = edge[i].v;
    166             if(y == f) continue;
    167             //printf("y = %d 
    ", y);
    168             DFS_1(y, x);
    169             //printf("merge %d -> %d 
    ", x, y);
    170             seg::del(deep[x], 1, n, rt[y]);
    171             rt[x] = seg::merge(rt[x], rt[y], d[x]);
    172             //printf("Ans = %lld 
    ", Ans);
    173         }
    174         return;
    175     }
    176 
    177     inline void solve() {
    178         seg::tot = 0;
    179         seg::large[0] = seg::largeD[0] = -INF;
    180         Ans = -INF;
    181         memset(rt + 1, 0, n * sizeof(int));
    182         for(int i = 1; i <= n; i++) v[i].clear();
    183 
    184         for(int i = 1; i <= m; i++) {
    185             int x = node[i].x, y = node[i].y, z = node[i].w;
    186             if(x != z) {
    187                 v[x].push_back(i);
    188             }
    189             if(y != z) {
    190                 v[y].push_back(i);
    191             }
    192         }
    193 
    194         DFS_1(1, 0);
    195         if(Ans < (LL)(-3e18)) puts("F");
    196         else printf("%lld
    ", Ans);
    197         return;
    198     }
    199 }
    200 
    201 namespace Stwo { /// lca = 1
    202     inline void solve() {
    203 
    204         return;
    205     }
    206 }
    207 
    208 inline void solve() {
    209     scanf("%d", &n);
    210     LL z;
    211     for(int i = 1, x, y; i < n; i++) {
    212         scanf("%d%d%lld", &x, &y, &z);
    213         add(x, y, z);
    214         add(y, x, z);
    215     }
    216 
    217     DFS(1, 0);
    218     prework();
    219 
    220     scanf("%d", &m);
    221     bool S1 = true, S2 = true;
    222     int lastLca = -1;
    223     for(int i = 1, x, y; i <= m; i++) {
    224         scanf("%d%d%lld", &x, &y, &z);
    225         node[i].x = x;
    226         node[i].y = y;
    227         node[i].z = z;
    228         node[i].val = dis(x, y) - z;
    229         int temp = lca(x, y);
    230         if(lastLca == -1) lastLca = temp;
    231         else if(lastLca != temp) S2 = false;
    232         if(visLca[temp]) S1 = false;
    233         else visLca.set(temp);
    234         node[i].w = temp;
    235     }
    236 
    237     if(S1) {
    238         Sone::solve();
    239         return;
    240     }
    241     if(S2) {
    242         Stwo::solve();
    243         return;
    244     }
    245 
    246     return;
    247 }
    248 
    249 int main() {
    250 
    251     freopen("in.in", "r", stdin);
    252     freopen("my.out", "w", stdout);
    253 
    254     for(int i = 2; i < N; i++) pw[i] = pw[i >> 1] + 1;
    255 
    256     int T;
    257     scanf("%d", &T);
    258     while(T--) {
    259         solve();
    260         if(T) clear();
    261     }
    262     return 0;
    263 }
    15分S1代码

    接下来是S2的lca全部为1的部分分。

    继续抄题解。

    我的理解是,首先把2 * 总价值转化成链长之和 - 代价之和 + 蓝点距离 + 绿点距离。我们尝试新建两个点来表示出这个东西。

    首先把蓝点距离转化成蓝a深度 + 蓝b深度 - 2 * 红点深度。

    对于一条链a,我们在绿a处挂上一个节点绿a',使得它到绿a的距离为链长 - 代价 + 蓝a深度。

    然后我们发现,这样两个附加点的距离正好凑出了上面那个2 * 总价值,只要再减去2 * 红点深度就行了。

    有这个结论是因为边权非负。那么我们新加的边不是有一堆负权吗?为什么成立呢?

    因为我们可以给这些新加的边(假装加上了)加上一个很大的正值来达到非负。为什么这个方法在一般的树上不适用呢?因为我们不知道直径上有多少条边加了这个大正值。但是本题中会有恰两条边加上这个正值。

    所以做法就出来了。具体来说,我们DFS这棵树,然后在每个蓝a处把绿a'加入点集,同理在绿a处把蓝a'加入点集。

    然后合并点集的同时更新答案。注意当前点为根的时候不能更新,因为可能会把蓝a'和绿a'的距离算入答案。也没必要更新,因为根不可能作为红点。

    注意只需要挂可能成为蓝a的对应的绿a',就是说一条链直上直下的时候有一个点不用加。

      1 #include <bits/stdc++.h>
      2 
      3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
      4 
      5 using namespace std;
      6 
      7 typedef long long LL;
      8 const int N = 300010;
      9 const LL INF = 4e18;
     10 
     11 struct Edge {
     12     int nex, v;
     13     LL len;
     14 }edge[N << 1]; int tp = 1;
     15 
     16 struct Node {
     17     int x, y, w;
     18     LL val, z;
     19 }node[N];
     20 
     21 struct Data {
     22     int a, b;
     23     Data(int A = 0, int B = 0) : a(A), b(B) {}
     24 }data[N];
     25 
     26 int e[N], num2, pos2[N], ST[N][20], pw[N], deep[N], n, m, fa[N], fr[N];
     27 LL d[N];
     28 std::bitset<N> visLca;
     29 
     30 inline void add(int x, int y, LL z) {
     31     tp++;
     32     edge[tp].v = y;
     33     edge[tp].len = z;
     34     edge[tp].nex = e[x];
     35     e[x] = tp;
     36     return;
     37 }
     38 
     39 inline void clear() {
     40     memset(e + 1, 0, n * sizeof(int));
     41     visLca.reset();
     42     tp = 1;
     43     num2 = 0;
     44     return;
     45 }
     46 
     47 void DFS(int x, int f) {
     48     pos2[x] = ++num2;
     49     ST[num2][0] = x;
     50     deep[x] = deep[f] + 1;
     51     fa[x] = f;
     52     forson(x, i) {
     53         int y = edge[i].v;
     54         if(y == f) {
     55             continue;
     56         }
     57         d[y] = d[x] + edge[i].len;
     58         DFS(y, x);
     59         ST[++num2][0] = x;
     60     }
     61     return;
     62 }
     63 
     64 inline void prework() {
     65     for(int j = 1; j <= pw[num2]; j++) {
     66         for(int i = 1; i + (1 << j) - 1 <= num2; i++) {
     67             if(deep[ST[i][j - 1]] < deep[ST[i + (1 << (j - 1))][j - 1]]) {
     68                 ST[i][j] = ST[i][j - 1];
     69             }
     70             else {
     71                 ST[i][j] = ST[i + (1 << (j - 1))][j - 1];
     72             }
     73         }
     74     }
     75     return;
     76 }
     77 
     78 inline int lca(int x, int y) {
     79     x = pos2[fr[x]];
     80     y = pos2[fr[y]];
     81     if(x > y) std::swap(x, y);
     82     int t = pw[y - x + 1];
     83     if(deep[ST[x][t]] < deep[ST[y - (1 << t) + 1][t]]) {
     84         return ST[x][t];
     85     }
     86     else {
     87         return ST[y - (1 << t) + 1][t];
     88     }
     89 }
     90 
     91 inline LL dis(int x, int y) {
     92     if(!x || !y) return -INF;
     93     if(x > n && (x - n + 1) / 2 == (y - n + 1) / 2) return -INF;
     94     //if(x > n) printf("dis %d %d = %lld 
    ", x, y, d[x] + d[y] - 2 * d[lca(x, y)]);
     95     return d[x] + d[y] - 2 * d[lca(x, y)];
     96 }
     97 
     98 namespace Sone { /// lca != lca
     99     LL Ans;
    100     int rt[N];
    101     std::vector<int> v[N];
    102     namespace seg {
    103         const int M = 10000010;
    104 
    105         int ls[M], rs[M], tot;
    106         LL large[M], largeD[M];
    107 
    108         inline void pushup(int o) {
    109             large[o] = std::max(large[ls[o]], large[rs[o]]);
    110             largeD[o] = std::max(largeD[ls[o]], largeD[rs[o]]);
    111             return;
    112         }
    113         void insert(int p, LL v, LL v2, LL v3, int l, int r, int &o) {
    114             if(!o) {
    115                 o = ++tot;
    116                 ls[o] = rs[o] = 0;
    117                 large[o] = largeD[o] = -INF;
    118             }
    119             if(l == r) {
    120                 large[o] = std::max(large[o], v);
    121                 largeD[o] = std::max(largeD[o], v + v2);
    122                 return;
    123             }
    124             int mid = (l + r) >> 1;
    125             if(p <= mid) {
    126                 Ans = std::max(Ans, largeD[rs[o]] + v - v3);
    127                 insert(p, v, v2, v3, l, mid, ls[o]);
    128             }
    129             else {
    130                 Ans = std::max(Ans, large[ls[o]] + v + v2 - v3);
    131                 insert(p, v, v2, v3, mid + 1, r, rs[o]);
    132             }
    133             pushup(o);
    134             return;
    135         }
    136         int merge(int x, int y, LL v) {
    137             //printf("merge x = %d y = %d v = %lld 
    ", x, y, v);
    138             if(!x || !y) return x | y;
    139             Ans = std::max(Ans, std::max(large[ls[x]] + largeD[rs[y]], large[ls[y]] + largeD[rs[x]]) - v);
    140             large[x] = std::max(large[x], large[y]);
    141             largeD[x] = std::max(largeD[x], largeD[y]);
    142             ls[x] = merge(ls[x], ls[y], v);
    143             rs[x] = merge(rs[x], rs[y], v);
    144             return x;
    145         }
    146         void del(int p, int l, int r, int o) {
    147             if(!o) {
    148                 return;
    149             }
    150             if(l == r) {
    151                 large[o] = largeD[o] = -INF;
    152                 return;
    153             }
    154             int mid = (l + r) >> 1;
    155             if(p <= mid) {
    156                 large[rs[o]] = largeD[rs[o]] = -INF;
    157                 del(p, l, mid, ls[o]);
    158             }
    159             else {
    160                 del(p, mid + 1, r, rs[o]);
    161             }
    162             pushup(o);
    163             return;
    164         }
    165     }
    166 
    167     void DFS_1(int x, int f) {
    168         //printf("x = %d 
    ", x);
    169         for(int i = 0; i < (int)v[x].size(); i++) {
    170             int t = v[x][i];
    171             //printf("x = %d insert p = %d w = %d  v1 = %lld  v2 = %lld 
    ", x, deep[node[t].w], node[t].w, node[t].val, d[node[t].w]);
    172             seg::insert(deep[node[t].w], node[t].val, d[node[t].w], d[x], 1, n, rt[x]);
    173         }
    174         forson(x, i) {
    175             int y = edge[i].v;
    176             if(y == f) continue;
    177             //printf("y = %d 
    ", y);
    178             DFS_1(y, x);
    179             //printf("merge %d -> %d 
    ", x, y);
    180             seg::del(deep[x], 1, n, rt[y]);
    181             rt[x] = seg::merge(rt[x], rt[y], d[x]);
    182             //printf("Ans = %lld 
    ", Ans);
    183         }
    184         return;
    185     }
    186 
    187     inline void solve() {
    188         seg::tot = 0;
    189         seg::large[0] = seg::largeD[0] = -INF;
    190         Ans = -INF;
    191         memset(rt + 1, 0, n * sizeof(int));
    192         for(int i = 1; i <= n; i++) v[i].clear();
    193 
    194         for(int i = 1; i <= m; i++) {
    195             int x = node[i].x, y = node[i].y, z = node[i].w;
    196             if(x != z) {
    197                 v[x].push_back(i);
    198             }
    199             if(y != z) {
    200                 v[y].push_back(i);
    201             }
    202         }
    203 
    204         DFS_1(1, 0);
    205         if(Ans < (LL)(-3e18)) puts("F");
    206         else printf("%lld
    ", Ans);
    207         return;
    208     }
    209 }
    210 
    211 namespace Stwo { /// lca = 1
    212     /*Edge EDGE[N << 1]; int TP;
    213     int E[N], use[N], Time, fr[N];
    214     inline void ADD(int x, int y, LL z) {
    215         TP++;
    216         EDGE[TP].v = y;
    217         EDGE[TP].len = z;
    218         EDGE[TP].nex = E[x];
    219         E[x] = TP;
    220         return;
    221     }
    222     inline void work(int x) {
    223         if(use[x] != Time) {
    224             use[x] = Time;
    225             E[x] = 0;
    226             ? = ?;
    227         }
    228         return;
    229     }*/
    230     std::vector<int> v[N];
    231     LL Ans;
    232 
    233     inline void update(Data &x, const Data &y, const LL &v) {
    234         //printf("update v = %lld 
    ", v);
    235         LL d12 = dis(x.a, x.b), d34 = dis(y.a, y.b);
    236         LL d13 = dis(x.a, y.a), d14 = dis(x.a, y.b);
    237         LL d23 = dis(x.b, y.a), d24 = dis(x.b, y.b);
    238         Ans = std::max(Ans, std::max(std::max(d13, d14), std::max(d23, d24)) - v);
    239         int xa = x.a, xb = x.b;
    240         if(d34 > d12) {
    241             x = y;
    242             d12 = d34;
    243         }
    244         if(d13 > d12) {
    245             x = Data(xa, y.a);
    246             d12 = d13;
    247         }
    248         if(d14 > d12) {
    249             x = Data(xa, y.b);
    250             d12 = d14;
    251         }
    252         if(d23 > d12) {
    253             x = Data(xb, y.a);
    254             d12 = d23;
    255         }
    256         if(d24 > d12) {
    257             x = Data(xb, y.b);
    258         }
    259         if(!x.a) x = y;
    260         //printf("Ans = %lld 
    ", Ans);
    261         return;
    262     }
    263 
    264     inline void update(Data &x, const int &a, const LL &v) {
    265         //printf("insert v = %lld 
    ", v);
    266         LL d1 = dis(x.a, a), d2 = dis(x.b, a), d3 = dis(x.a, x.b);
    267         Ans = std::max(Ans, std::max(d1, d2) - v);
    268         int xa = x.a, xb = x.b;
    269         if(d1 > d3) {
    270             x.b = a;
    271             d3 = d1;
    272         }
    273         if(d2 > d3) {
    274             x = Data(xb, a);
    275         }
    276         if(!x.a) x.a = a;
    277         //printf("Ans = %lld 
    ", Ans);
    278         return;
    279     }
    280 
    281     void DFS_1(int x, int f) {
    282         forson(x, i) {
    283             int y = edge[i].v;
    284             if(y == f) continue;
    285             DFS_1(y, x);
    286             if(f) update(data[x], data[y], d[x] << 1);
    287             //printf("data x : %d %d 
    ", data[x].a, data[x].b);
    288         }
    289         if(f) {
    290             for(int i = 0; i < (int)v[x].size(); i++) {
    291                 int t = v[x][i];
    292                 update(data[x], t, d[x] << 1);
    293             }
    294         }
    295         return;
    296     }
    297 
    298     inline void solve() {
    299 
    300         //printf("S2 inside 
    ");
    301 
    302         for(int i = 1; i <= n; i++) {
    303             v[i].clear();
    304             v[i].resize(0);
    305             data[i].a = data[i].b = 0;
    306         }
    307         Ans = -INF;
    308         for(int i = 1; i <= m; i++) {
    309             int x = node[i].x, y = node[i].y, z = node[i].w;
    310             if(x != z) {
    311                 fr[n + i * 2 - 1] = y;
    312                 d[n + i * 2 - 1] = d[y] + d[x] + node[i].val - node[i].z;
    313                 v[x].push_back(n + i * 2 - 1);
    314                 //printf("%d : d = %lld fr = %d 
    ", n + i * 2 - 1, d[n + i * 2 - 1], fr[n + i * 2 - 1]);
    315             }
    316             if(y != z) {
    317                 fr[n + i * 2] = x;
    318                 d[n + i * 2] = d[x] + d[y] + node[i].val - node[i].z;
    319                 v[y].push_back(n + i * 2);
    320                 //printf("%d : d = %lld fr = %d 
    ", n + i * 2, d[n + i * 2], fr[n + i * 2]);
    321             }
    322         }
    323         //puts("");
    324         DFS_1(1, 0);
    325 
    326         if(Ans < (LL)-3e18) puts("F");
    327         else printf("%lld
    ", Ans >> 1);
    328         return;
    329     }
    330 }
    331 
    332 inline void solve() {
    333     scanf("%d", &n);
    334     for(int i = 1; i <= n; i++) {
    335         fr[i] = i;
    336     }
    337     LL z;
    338     for(int i = 1, x, y; i < n; i++) {
    339         scanf("%d%d%lld", &x, &y, &z);
    340         add(x, y, z);
    341         add(y, x, z);
    342     }
    343 
    344     DFS(1, 0);
    345     prework();
    346 
    347     scanf("%d", &m);
    348     bool S1 = true, S2 = true;
    349     int lastLca = -1;
    350     for(int i = 1, x, y; i <= m; i++) {
    351         scanf("%d%d%lld", &x, &y, &z);
    352         node[i].x = x;
    353         node[i].y = y;
    354         node[i].z = z;
    355         node[i].val = dis(x, y) - z;
    356         int temp = lca(x, y);
    357         if(lastLca == -1) lastLca = temp;
    358         else if(lastLca != temp) S2 = false;
    359         if(visLca[temp]) S1 = false;
    360         else visLca.set(temp);
    361         node[i].w = temp;
    362     }
    363 
    364     if(S1) {
    365         Sone::solve();
    366         return;
    367     }
    368     if(S2) {
    369         Stwo::solve();
    370         return;
    371     }
    372 
    373     return;
    374 }
    375 
    376 int main() {
    377 
    378     //freopen("in.in", "r", stdin);
    379     //freopen("my.out", "w", stdout);
    380 
    381     for(int i = 2; i < N; i++) pw[i] = pw[i >> 1] + 1;
    382 
    383     int T;
    384     scanf("%d", &T);
    385     while(T--) {
    386         solve();
    387         if(T) clear();
    388     }
    389     return 0;
    390 }
    35分S1+S2代码

    终于到正解了...考虑两条链如果有交,那么要么是直上直下的交,lca不同;要么是交了一段可能不直上直下的,lca相同。

    那么lca不同的所有情况直接调用S1即可。lca相同的情况,可能在很多点相同。此时我们枚举每个点,把以这些点为lca的链都提出来建虚树,套用S2即可。

    考虑为什么套用S1的时候不会把本来属于S2的情况算得更优。

    注意到一个细节,就是S1中如果两个链加到线段树的同一下标上(lca相同),我们是不会把这两条链拿去更新答案的。于是S1中更新的就都是lca不同的啦!

      1 #include <bits/stdc++.h>
      2 
      3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
      4 
      5 typedef long long LL;
      6 const int N = 300010;
      7 const LL INF = 4e18;
      8 
      9 struct Edge {
     10     int nex, v;
     11     LL len;
     12 }edge[N << 1]; int tp = 1;
     13 
     14 struct Node {
     15     int x, y, w;
     16     LL val, z;
     17 }node[N];
     18 
     19 struct Data {
     20     int a, b;
     21     Data(int A = 0, int B = 0) : a(A), b(B) {}
     22 }data[N];
     23 
     24 int e[N], num2, pos2[N], ST[N][20], pw[N], deep[N], n, m, fa[N], fr[N];
     25 LL d[N], Ans;
     26 
     27 inline void add(int x, int y, LL z) {
     28     tp++;
     29     edge[tp].v = y;
     30     edge[tp].len = z;
     31     edge[tp].nex = e[x];
     32     e[x] = tp;
     33     return;
     34 }
     35 
     36 inline void clear() {
     37     memset(e + 1, 0, n * sizeof(int));
     38     tp = 1;
     39     num2 = 0;
     40     return;
     41 }
     42 
     43 void DFS(int x, int f) {
     44     pos2[x] = ++num2;
     45     ST[num2][0] = x;
     46     deep[x] = deep[f] + 1;
     47     fa[x] = f;
     48     forson(x, i) {
     49         int y = edge[i].v;
     50         if(y == f) {
     51             continue;
     52         }
     53         d[y] = d[x] + edge[i].len;
     54         DFS(y, x);
     55         ST[++num2][0] = x;
     56     }
     57     return;
     58 }
     59 
     60 inline void prework() {
     61     for(int j = 1; j <= pw[num2]; j++) {
     62         for(int i = 1; i + (1 << j) - 1 <= num2; i++) {
     63             if(deep[ST[i][j - 1]] < deep[ST[i + (1 << (j - 1))][j - 1]]) {
     64                 ST[i][j] = ST[i][j - 1];
     65             }
     66             else {
     67                 ST[i][j] = ST[i + (1 << (j - 1))][j - 1];
     68             }
     69         }
     70     }
     71     return;
     72 }
     73 
     74 inline int lca(int x, int y) {
     75     x = pos2[fr[x]];
     76     y = pos2[fr[y]];
     77     if(x > y) std::swap(x, y);
     78     int t = pw[y - x + 1];
     79     if(deep[ST[x][t]] < deep[ST[y - (1 << t) + 1][t]]) {
     80         return ST[x][t];
     81     }
     82     else {
     83         return ST[y - (1 << t) + 1][t];
     84     }
     85 }
     86 
     87 inline LL dis(int x, int y) {
     88     if(!x || !y) return -INF;
     89     return d[x] + d[y] - 2 * d[lca(x, y)];
     90 }
     91 
     92 inline bool cmp(const int &a, const int &b) {
     93     return pos2[a] < pos2[b];
     94 }
     95 
     96 namespace Sone { /// lca != lca
     97     int rt[N];
     98     std::vector<int> v[N];
     99     namespace seg {
    100         const int M = 10000010;
    101 
    102         int ls[M], rs[M], tot;
    103         LL large[M], largeD[M];
    104 
    105         inline void pushup(int o) {
    106             large[o] = std::max(large[ls[o]], large[rs[o]]);
    107             largeD[o] = std::max(largeD[ls[o]], largeD[rs[o]]);
    108             return;
    109         }
    110         void insert(int p, LL v, LL v2, LL v3, int l, int r, int &o) {
    111             if(!o) {
    112                 o = ++tot;
    113                 ls[o] = rs[o] = 0;
    114                 large[o] = largeD[o] = -INF;
    115             }
    116             if(l == r) {
    117                 large[o] = std::max(large[o], v);
    118                 largeD[o] = std::max(largeD[o], v + v2);
    119                 return;
    120             }
    121             int mid = (l + r) >> 1;
    122             if(p <= mid) {
    123                 Ans = std::max(Ans, largeD[rs[o]] + v - v3);
    124                 insert(p, v, v2, v3, l, mid, ls[o]);
    125             }
    126             else {
    127                 Ans = std::max(Ans, large[ls[o]] + v + v2 - v3);
    128                 insert(p, v, v2, v3, mid + 1, r, rs[o]);
    129             }
    130             pushup(o);
    131             return;
    132         }
    133         int merge(int x, int y, LL v) {
    134             if(!x || !y) return x | y;
    135             Ans = std::max(Ans, std::max(large[ls[x]] + largeD[rs[y]], large[ls[y]] + largeD[rs[x]]) - v);
    136             large[x] = std::max(large[x], large[y]);
    137             largeD[x] = std::max(largeD[x], largeD[y]);
    138             ls[x] = merge(ls[x], ls[y], v);
    139             rs[x] = merge(rs[x], rs[y], v);
    140             return x;
    141         }
    142         void del(int p, int l, int r, int o) {
    143             if(!o) {
    144                 return;
    145             }
    146             if(l == r) {
    147                 large[o] = largeD[o] = -INF;
    148                 return;
    149             }
    150             int mid = (l + r) >> 1;
    151             if(p <= mid) {
    152                 large[rs[o]] = largeD[rs[o]] = -INF;
    153                 del(p, l, mid, ls[o]);
    154             }
    155             else {
    156                 del(p, mid + 1, r, rs[o]);
    157             }
    158             pushup(o);
    159             return;
    160         }
    161     }
    162 
    163     void DFS_1(int x, int f) {
    164         for(int i = 0; i < (int)v[x].size(); i++) {
    165             int t = v[x][i];
    166             seg::insert(deep[node[t].w], node[t].val, d[node[t].w], d[x], 1, n, rt[x]);
    167         }
    168         forson(x, i) {
    169             int y = edge[i].v;
    170             if(y == f) continue;
    171             DFS_1(y, x);
    172             seg::del(deep[x], 1, n, rt[y]);
    173             rt[x] = seg::merge(rt[x], rt[y], d[x]);
    174         }
    175         return;
    176     }
    177 
    178     inline void solve() {
    179         seg::tot = 0;
    180         seg::large[0] = seg::largeD[0] = -INF;
    181         memset(rt + 1, 0, n * sizeof(int));
    182         for(int i = 1; i <= n; i++) v[i].clear();
    183 
    184         for(int i = 1; i <= m; i++) {
    185             int x = node[i].x, y = node[i].y, z = node[i].w;
    186             if(x != z) {
    187                 v[x].push_back(i);
    188             }
    189             if(y != z) {
    190                 v[y].push_back(i);
    191             }
    192         }
    193 
    194         DFS_1(1, 0);
    195         return;
    196     }
    197 }
    198 
    199 namespace Stwo { /// lca = 1
    200     Edge EDGE[N << 1]; int TP;
    201     int E[N], use[N], Time, cnt, imp[N], stk[N], top;
    202     std::vector<int> v[N], vx[N];
    203 
    204     inline void ADD(int x, int y) {
    205         TP++;
    206         EDGE[TP].v = y;
    207         EDGE[TP].nex = E[x];
    208         E[x] = TP;
    209         return;
    210     }
    211 
    212     inline void work(int x) {
    213         if(use[x] != Time) {
    214             use[x] = Time;
    215             E[x] = 0;
    216             v[x].clear();
    217             data[x].a = data[x].b = 0;
    218         }
    219         return;
    220     }
    221 
    222     inline void update(Data &x, const Data &y, const LL &v) {
    223         LL d12 = dis(x.a, x.b), d34 = dis(y.a, y.b);
    224         LL d13 = dis(x.a, y.a), d14 = dis(x.a, y.b);
    225         LL d23 = dis(x.b, y.a), d24 = dis(x.b, y.b);
    226         Ans = std::max(Ans, (std::max(std::max(d13, d14), std::max(d23, d24)) - v) >> 1);
    227         int xa = x.a, xb = x.b;
    228         if(d34 > d12) {
    229             x = y;
    230             d12 = d34;
    231         }
    232         if(d13 > d12) {
    233             x = Data(xa, y.a);
    234             d12 = d13;
    235         }
    236         if(d14 > d12) {
    237             x = Data(xa, y.b);
    238             d12 = d14;
    239         }
    240         if(d23 > d12) {
    241             x = Data(xb, y.a);
    242             d12 = d23;
    243         }
    244         if(d24 > d12) {
    245             x = Data(xb, y.b);
    246         }
    247         if(!x.a) x = y;
    248         return;
    249     }
    250 
    251     inline void update(Data &x, const int &a, const LL &v) {
    252         LL d1 = dis(x.a, a), d2 = dis(x.b, a), d3 = dis(x.a, x.b);
    253         Ans = std::max(Ans, (std::max(d1, d2) - v) >> 1);
    254         int xa = x.a, xb = x.b;
    255         if(d1 > d3) {
    256             x.b = a;
    257             d3 = d1;
    258         }
    259         if(d2 > d3) {
    260             x = Data(xb, a);
    261         }
    262         if(!x.a) x.a = a;
    263         return;
    264     }
    265 
    266     void dfs(int x, int f) {
    267         for(int i = E[x]; i; i = EDGE[i].nex) {
    268             int y = EDGE[i].v;
    269             if(y == f) continue;
    270             dfs(y, x);
    271             if(f) update(data[x], data[y], d[x] << 1);
    272         }
    273         if(f) {
    274             for(int i = 0; i < (int)v[x].size(); i++) {
    275                 int t = v[x][i];
    276                 update(data[x], t, d[x] << 1);
    277             }
    278         }
    279         return;
    280     }
    281 
    282     inline void build_t() {
    283         std::sort(imp + 1, imp + cnt + 1, cmp);
    284         cnt = std::unique(imp + 1, imp + cnt + 1) - imp - 1;
    285 
    286         stk[top = 1] = imp[1];
    287         for(int i = 2; i <= cnt; i++) {
    288             int x = imp[i], y = lca(x, stk[top]);
    289             work(x); work(y);
    290             while(top > 1 && pos2[y] <= pos2[stk[top - 1]]) {
    291                 ADD(stk[top - 1], stk[top]);
    292                 top--;
    293             }
    294             if(y != stk[top]) {
    295                 ADD(y, stk[top]);
    296                 stk[top] = y;
    297             }
    298             stk[++top] = x;
    299         }
    300         while(top > 1) {
    301             ADD(stk[top - 1], stk[top]);
    302             top--;
    303         }
    304         return;
    305     }
    306 
    307     inline void solve() {
    308 
    309         for(int i = 1; i <= n; i++) {
    310             vx[i].clear();
    311         }
    312 
    313         for(int i = 1; i <= m; i++) {
    314             vx[node[i].w].push_back(i);
    315         }
    316 
    317         for(int rt = 1; rt <= n; rt++) {
    318             if(!vx[rt].size()) continue;
    319             ++Time;
    320             TP = cnt = 0;
    321             work(rt);
    322             imp[++cnt] = rt;
    323             for(int j = 0; j < (int)vx[rt].size(); j++) {
    324                 int i = vx[rt][j];
    325                 int x = node[i].x, y = node[i].y, z = node[i].w;
    326                 work(x); work(y);
    327                 imp[++cnt] = x;
    328                 imp[++cnt] = y;
    329                 if(x != z) {
    330                     fr[n + i * 2 - 1] = y;
    331                     d[n + i * 2 - 1] = d[y] + d[x] + node[i].val - node[i].z;
    332                     v[x].push_back(n + i * 2 - 1);
    333                 }
    334                 if(y != z) {
    335                     fr[n + i * 2] = x;
    336                     d[n + i * 2] = d[x] + d[y] + node[i].val - node[i].z;
    337                     v[y].push_back(n + i * 2);
    338                 }
    339             }
    340             build_t();
    341             dfs(rt, 0);
    342         }
    343         return;
    344     }
    345 }
    346 
    347 inline void solve() {
    348     Ans = -INF;
    349     scanf("%d", &n);
    350     for(int i = 1; i <= n; i++) {
    351         fr[i] = i;
    352     }
    353     LL z;
    354     for(int i = 1, x, y; i < n; i++) {
    355         scanf("%d%d%lld", &x, &y, &z);
    356         add(x, y, z);
    357         add(y, x, z);
    358     }
    359 
    360     DFS(1, 0);
    361     prework();
    362 
    363     scanf("%d", &m);
    364     for(int i = 1, x, y; i <= m; i++) {
    365         scanf("%d%d%lld", &x, &y, &z);
    366         node[i].x = x;
    367         node[i].y = y;
    368         node[i].z = z;
    369         node[i].val = dis(x, y) - z;
    370         node[i].w = lca(x, y);
    371     }
    372 
    373     Sone::solve();
    374     Stwo::solve();
    375 
    376     if(Ans < (LL)-1e18) puts("F");
    377     else printf("%lld
    ", Ans);
    378     return;
    379 }
    380 
    381 int main() {
    382 
    383     for(int i = 2; i < N; i++) pw[i] = pw[i >> 1] + 1;
    384 
    385     int T;
    386     scanf("%d", &T);
    387     while(T--) {
    388         solve();
    389         if(T) clear();
    390     }
    391     return 0;
    392 }
    AC代码

    这什么鬼题啊...搞了4天,结果写完啥都没学到......

  • 相关阅读:
    Python之路【第四十五篇】:django日更
    Python之路【第四十四篇】:django日更
    C++ 调用动态链接库
    博客园美化
    postgresql中的UUID
    使用rustup安装rust环境
    MySQL 查询做排名
    Docker
    CentOS安装Docker和基础操作
    切换CentOS7的yum源为阿里源
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10679339.html
Copyright © 2011-2022 走看看