样例不过树剖在线求条
查看原帖
样例不过树剖在线求条
1114241
vectorxyz楼主2024/10/3 22:26
#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;
template<typename T>
T read(T x)
{
    T opt = 1, sum = 0;
    char ch = getchar();
    while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
    while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
    return opt * sum;
}
#define read read(0ll)
const int N = 1e5 + 5;
int w[N], dep[N], fa[N], sz[N], temp[N], son[N], top[N], _, id[N], a[N];
pair<int, int> yexo[N];
vector<int> g[N];
void dfs1(int u, int f, int deep)
{
    dep[u] = deep;
    fa[u] = f;
    sz[u] = 1;
    int maxn = -1;
    for(int i = 0;i < g[u].size();i ++ ){
        int v = g[u][i];
        if(v == f) continue;
        dfs1(v, u, deep + 1);
        temp[v] = w[u];
        sz[u] += sz[v];
        if(sz[v] > maxn) 
        {
            maxn = sz[v];
            son[u] = v;
        }
    }
}

void dfs2(int u, int topf)
{
    top[u] = topf;
    id[u] = ++_;
    a[_] = temp[u];
    if(!son[u]) return ;
    dfs2(son[u], topf);
    for(int i = 0;i < g[u].size();i ++ ){
        int v = g[u][i];
        if(v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}
struct Segment
{
    struct node
    {
        int l, r, sum, maxn, minn, lazy;
    }tr[N << 2];
    void push_up(int u)
    {
        tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
        tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
        tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
    }
    void pushdown(int u)
    {
        tr[u << 1].lazy ^= 1, tr[u << 1 | 1].lazy ^= 1;
        tr[u << 1].maxn = -tr[u << 1].maxn, tr[u << 1 | 1].maxn = -tr[u << 1 | 1].maxn;
        tr[u << 1].minn = -tr[u << 1].minn, tr[u << 1 | 1].minn = -tr[u << 1 | 1].minn;
        tr[u << 1].sum = -tr[u << 1].sum, tr[u << 1 | 1].sum = -tr[u << 1 | 1].sum;
        swap(tr[u << 1].maxn, tr[u << 1].minn);
        swap(tr[u << 1 | 1].maxn, tr[u << 1 | 1].minn);
        tr[u].lazy = 0;
    }
    void build(int u, int l, int r)
    {
        tr[u].l = l, tr[u].r = r;
        tr[u].lazy = 0;tr[u].maxn = INT_MIN, tr[u].minn = INT_MAX;
        if(l == r) {
            tr[u].sum = tr[u].maxn = tr[u].minn = a[l]; return ;
        }
        int mid = (l + r) / 2;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        push_up(u);
    }
    void reupdate(int u, int l, int r, int ll, int rr)
    {
        if(ll <= l && r <= rr)
        {
            tr[u].lazy ^= 1;
            tr[u].maxn = -tr[u].maxn, tr[u].minn = -tr[u].minn, swap(tr[u].maxn, tr[u].minn);
            tr[u].sum = -tr[u].sum;
            return ;
        }
        if(tr[u].lazy) pushdown(u);
        int mid = (l + r) / 2;
        if(ll <= mid) reupdate(u << 1, l, mid, ll, rr);
        if(rr >  mid) reupdate(u << 1, mid + 1, r, ll, rr);
        push_up(u);
    }
    void update(int u, int l, int r, int q, int val)
    {
        if(l == r)
        {
            tr[u].maxn = tr[u].minn = tr[u].sum = val;
            return ;
        }
        if(tr[u].lazy) pushdown(u);
        int mid = (l + r) / 2;
        if(q <= mid) update(u << 1, l, mid, q, val);
        if(q >  mid) update(u << 1, mid + 1, r, q, val);
        push_up(u);
    }
    int querysum(int u, int l, int r, int ll, int rr)
    {
        if(ll <= l && r <= rr)
        {
            return tr[u].sum;
        }
        if(tr[u].lazy) pushdown(u);
        int mid = (l + r) / 2;
        int res = 0;
        if(ll <= mid) res += querysum(u << 1, l, mid, ll, rr);
        if(rr >  mid) res += querysum(u << 1, mid + 1, r, ll, rr);
        push_up(u);
        return res;
    }
    int querymaxn(int u, int l, int r, int ll, int rr)
    {
        if(ll <= l && r <= rr)
        {
            return tr[u].maxn;
        }
        if(tr[u].lazy) pushdown(u);
        int mid = (l + r) / 2;
        int res = INT_MIN;
        if(ll <= mid) res = max(res, querymaxn(u << 1, l, mid, ll, rr));
        if(rr >  mid) res = max(res, querymaxn(u << 1, mid + 1, r, ll, rr));
        push_up(u);
        return res;
    }
    int queryminn(int u, int l, int r, int ll, int rr)
    {
        if(ll <= l && r <= rr)
        {
            return tr[u].minn;
        }
        if(tr[u].lazy) pushdown(u);
        int mid = (l + r) / 2;
        int res = INT_MAX;
        if(ll <= mid) res = min(res, queryminn(u << 1, l, mid, ll, rr));
        if(rr >  mid) res = min(res, queryminn(u << 1, mid + 1, r, ll, rr));
        push_up(u);
        return res;
    }
}seg;
struct Tree
{
    void update(int x, int y)
    {
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            seg.reupdate(1, 1, n, id[top[x]], id[x]);
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x, y);
        seg.reupdate(1, 1, n, id[x] + 1, id[y]);
    }
    int querysum(int x, int y)
    {
        int res = 0;
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            res += seg.querysum(1, 1, n, id[top[x]], id[x]);
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x, y);
        res += seg.querysum(1, 1, n, id[x] + 1, id[y]);
        return res;
    }
    int querymaxn(int x, int y)
    {
        int res = INT_MIN;
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            res = max(res, seg.querymaxn(1, 1, n, id[top[x]], id[x]));
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x, y);
        res = max(res, seg.querymaxn(1, 1, n, id[x] + 1, id[y]));
        return res;
    }
    int queryminn(int x, int y)
    {
        int res = INT_MAX;
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            res = min(res, seg.queryminn(1, 1, n, id[top[x]], id[x]));
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x, y);
        res = min(res, seg.queryminn(1, 1, n, id[x] + 1, id[y]));
        return res;
    }
}tp;
signed main()
{
    n = read;
    for(int i = 1;i < n;i ++ ){
        int u = read, v = read;
        u ++, v ++ ;
        g[u].push_back(v), g[v].push_back(u);
        cin >> w[u];
        yexo[i].first = u, yexo[i].second = v;
    }
    dfs1(1, 0, 1), dfs2(1, 1);
    seg.build(1, 1, n);
    int m = read;
    while(m -- ){
        string s; cin >> s;
        if(s == "C"){
            int i = read, w = read; 
            int k;
            if(dep[yexo[i].first] > dep[yexo[i].second]) k = yexo[i].first;
            else k = yexo[i].second;
            seg.update(1, 1, n, id[k], w);
        }
        else if(s == "N"){
            int u = read, v = read;
            u ++, v ++ ;
            tp.update(u, v);
        }
        else if(s == "SUM"){
            int u = read, v = read;
            u ++ , v ++ ;
            cout << tp.querysum(u, v) << endl;
        }
        else if(s == "MAX"){
            int u = read, v = read;
            u ++, v ++ ;
            cout << tp.querymaxn(u, v) << endl;
        }
        else {
            int u = read, v = read;
            u ++ ,v ++ ;
            cout << tp.queryminn(u, v) << endl;
        }
    }
    return 0;
}

2024/10/3 22:26
加载中...