@loj - 2434 @ "ZJOI2018 'history


@description@

Nine poor girl is a love of reading.

During this time, she saw a very interesting novel, overhead world of this novel caught her interest.

The world has n cities, which are n cities exactly n-1 two-way link road, that is, any two cities can reach each other. 1 while the city is located in the center of the world, it occupied the city to dominate the world.

In the beginning, these n cities are not under the control of any country, but with the development of society, some cities will rise and form a national seize hegemony of the world. For convenience, we mark the first country to produce the rise of cities i is the i-th country. During the rise of the i-th city, the country i would i get the city to control all of the city on a path to the city.

The rise of a new city often means war and death, if the i-th country in the rise, the need to take control of an otherwise controlled country j (j ≠ i) of the city, then the state i j must declare war on the country and war.

Now, the poor know that, historically, the i-th city a total rise of ai times. However, the relative order of these events have not known, the only message is that in a city before the rise to dominate the world, the new city will not rise.

War is disastrous for the people. Poor definition of a rise of the disaster of war will be and how many different countries is the rise of the process (and the same country were many wars are only counted once). The poor want to know all the possible rise in the order, disaster degrees and the maximum is.

Meanwhile, the efforts of archaeologists, more and more historical data was excavated out, based on these new data, poor ai will make some amendments. Specifically, some poor ai will operate, will each add ax w. She hoped that after each modification, can calculate the maximum degree of disaster.

However, poor calculation of the complex was not interested, so she wants you to help her calculate these values.

Some additional questions to face:
the same city several times and the Rise of the country is the same country, which means that the same city twice in a row is not going to rise any country to go to war: because these cities had in its control of under.
In the evolution of history, the country i might be for some time without any control of the city. But this does not mean the demise of the country i, i rise when the city, the country i will still take control of the city on a path to i.

Input format
first line of input two integers n, m represents a number of operations and the number of cities.

The second line represents the input n integers ai of the initial values. Next, n - 1 lines of input two integers ui, vi (1≤ui, vi≤n) describes a path.

Next m lines each input two integers xi, wi represents the a [xi] plus wi.

Output format
output common line m + 1, the first row indicates the initial ai answer, the next m lines each represents the answer to this correction.

Sample input
. 5. 3
. 1. 1. 1. 1. 1
. 1 2
. 1. 3
2. 4
2. 5
2. 1
. 3. 1
. 4. 1
sample output
. 6
. 7
. 9
10

Sample explained
before the start of the correction, if 4, 1, 5, 3, 2, in accordance with the order of the rise of the city, it will be followed by war and 0, 1, 2, 1, 2 countries.
At this time it will produce a total of six pairs of hostile relations. It may prove to be the maximum of all rising order.

And prompt data range
n, m <= 4 * 10 ^ 5.

@solution@

Is a number of types of link-cut-tree access procedure through the color segments. Equivalently, we climb the statistical process color first position number appears.

How to make it the largest it? We consider the contribution of each point x. If two adjacent operating points from the same subtree of x, the point x will not contribute.
In other words, whether a contribution only with x p operating point at which the relevant sub-tree of x (x may be itself), and p is itself independent of what.

Note SUM [x] to x is within the subtree rooted sum ai, then remember mxs [x] = max {max {sum [u]}, a [x]}.
When 2 * mxs [x] <time = sum [x], may be arranged sum [x] These operations adjacent pairwise from the same sub-tree, then the maximum contribution to the sum [x] - 1; otherwise, the The maximum contribution is 2 * (sum [x] - mxs [x]).
Note that for the first time is not, because for the first time when x has no color.

This way, we can calculate the contribution without modification.

Consider how to maintain this value in the modification, because it is itself an access operation, it is not difficult to think of using lct.
When 2 * mxs [x]> When the sum [x], if both make sum [x] and mxs [x] plus w, the inequality remains unchanged and the contribution remains the same.
So: we make mxs [x] corresponds son (note mxs [x] x may also correspond to their own, then do not consider) as the most important son of x, then link-cut-tree wave.
At this point the light side to consider changes in the severity of side meets the requirements, not as directly as usual lct Jieshangqu heavy side. Heavy chain with a tag safeguard click.

the complexity? Every jump light side, sum of at least double, so jump up to O (log) times lighter side.

In fact, that is the link-cut-tree, as it is dynamic maintenance of chain split the tree. . .

@accepted code@

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 400000;
ll ans;
struct link_cut_tree{
    struct node{
        ll sum, mxs, tg, key;
        node *ch[2], *fa;
        int dir() {return fa->ch[1] == this;}
    }pl[MAXN + 5], *ncnt, *NIL;
    void maintain(node *x, ll k) {
        if( x == NIL ) return ;
        x->tg += k, x->sum += k, x->mxs += k;
    }
    void pushdown(node *x) {
        if( x->tg ) {
            maintain(x->ch[0], x->tg);
            maintain(x->ch[1], x->tg);
            x->tg = 0;
        }
    }
    link_cut_tree() {
        ncnt = NIL = &pl[0];
        NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL;
        NIL->sum = NIL->mxs = NIL->tg = 0;
    }
    node *newnode() {
        node *p = (++ncnt);
        p->ch[0] = p->ch[1] = p->fa = NIL;
        p->sum = p->mxs = p->tg = 0;
        return p;
    }
    void set_child(node *x, node *y, int d) {
        if( x != NIL ) x->ch[d] = y;
        if( y != NIL ) y->fa = x;
    }
    bool is_root(node *x) {
        return x->fa->ch[0] != x && x->fa->ch[1] != x;
    }
    void rotate(node *x) {
        node *y = x->fa; int d = x->dir();
        pushdown(y), pushdown(x);
        if( is_root(y) ) x->fa = y->fa;
        else set_child(y->fa, x, y->dir());
        set_child(y, x->ch[!d], d);
        set_child(x, y, !d);
    }
    void splay(node *x) {
        pushdown(x);
        while( !is_root(x) ) {
            node *y = x->fa;
            if( is_root(y) ) rotate(x);
            else {
                if( y->dir() == x->dir() )
                    rotate(y);
                else rotate(x);
                rotate(x);
            }
        }
    }
    node *find(node *x) {
        if( x == NIL ) return NIL;
        node *y = x;
        while( y->ch[0] != NIL ) pushdown(y), y = y->ch[0];
        splay(y);
        return y;
    }
    void update(node *x, int k) {
        node *y = NIL; x->key += k;
//      printf("! %d\n", k);
        while( x != NIL ) {
            splay(x);
            if( x->sum ) ans -= min(x->sum - 1, 2*(x->sum - x->mxs));
            x->sum += k;
            if( 2*x->mxs <= x->sum )
                x->ch[1] = NIL;
            y = find(y);
            if( x->mxs < y->sum ) {
                x->mxs = y->sum;
                if( 2*x->mxs > x->sum )
                    x->ch[1] = y;
            }
            if( x->mxs < x->key ) {
                x->ch[1] = NIL;
                x->mxs = x->key;
            }
            maintain(x->ch[0], k);
//          printf("%d : %lld %lld  \t | \t %d : %lld %lld\n", x - pl, x->mxs, x->sum, y - pl, y->mxs, y->sum);
            ans += min(x->sum - 1, 2*(x->sum - x->mxs));
            y = x, x = x->fa;
        }
//      printf("%lld\n", ans);
    }
}T;
vector<int>G[MAXN + 5];
void addedge(int u, int v) {
    G[u].push_back(v), G[v].push_back(u);
}
int a[MAXN + 5];
link_cut_tree::node *nd[MAXN + 5];
void dfs(int x, int f) {
    nd[x] = T.newnode();
    if( x != 1 ) nd[x]->fa = nd[f];
    T.update(nd[x], a[x]);
    for(int i=0;i<G[x].size();i++) {
        int p = G[x][i];
        if( p != f ) dfs(p, x);
    }
}
int main() {
    int n, m; scanf("%d%d", &n, &m);
    for(int i=1;i<=n;i++)
        scanf("%d", &a[i]);
    for(int i=1;i<n;i++) {
        int u, v; scanf("%d%d", &u, &v);
        addedge(u, v);
    }
    dfs(1, 0);
    printf("%lld\n", ans);
    for(int i=1;i<=m;i++) {
        int x, w; scanf("%d%d", &x, &w);
        T.update(nd[x], w);
        printf("%lld\n", ans);
    }
}

@details@

Parent-child relationship splay of the parent-child relationship does not correspond to the original tree! ! !

The function parameter list not to write long long int! ! ! !

Guess you like

Origin www.cnblogs.com/Tiw-Air-OAO/p/11654214.html