全wa求助!!!蹲一个dalao!!
查看原帖
全wa求助!!!蹲一个dalao!!
54356
Abmcar楼主2021/7/4 22:52
#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <vector>
#include <string>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#define Buff std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ll long long
#define inf LONG_LONG_MAX
#define Inf ll_MAX
#define endl "\n"

using namespace std;

const ll Maxn = 510000;
const ll Mod = 1e9 + 7;

ll n, m, cntNode, num[Maxn], deep[Maxn], father[Maxn], sons[Maxn], gson[Maxn], id[Maxn], top[Maxn];
ll ans[Maxn], tag[Maxn], temp[Maxn];
vector<ll> g[Maxn];

void dfs1(ll nowNode, ll fatherNode, ll nowDeep)
{
    deep[nowNode] = nowDeep;
    father[nowNode] = fatherNode;
    sons[nowNode] = 1;
    ll maxSons = -1;
    for (ll i = 0; i < g[nowNode].size(); i++)
    {
        ll nextNode = g[nowNode][i];
        if (nextNode == fatherNode)
            continue;
        dfs1(nextNode, nowNode, nowDeep + 1);
        sons[nowNode] += sons[nextNode];
        if (maxSons < sons[nextNode])
        {
            maxSons = sons[nextNode];
            gson[nowNode] = nextNode;
        }
    }
}

void dfs2(ll nowNode, ll topNode)
{
    id[nowNode] = ++cntNode;
    num[cntNode] = temp[nowNode];
    top[nowNode] = topNode;
    if (!gson[nowNode])
        return;
    dfs2(gson[nowNode], topNode);
    for (ll i = 0; i < g[nowNode].size(); i++)
    {
        ll nextNode = g[nowNode][i];
        if (nextNode == father[nowNode] || nextNode == gson[nowNode])
            continue;
        dfs2(nextNode, nextNode);
    }
}

inline ll lc(ll x)
{
    return x * 2;
}

inline ll rc(ll x)
{
    return x * 2 + 1;
}

inline void pushUp(ll x)
{
    ans[x] = ans[lc(x)] + ans[rc(x)];
}

void build(long long pos, long long l, long long r)
{
    tag[pos] = 0;
    if (l == r)
    {
        ans[pos] = num[l];
        return;
    }
    long long mid = (l + r) / 2;
    build(lc(pos), l, mid);
    build(rc(pos), mid + 1, r);
    pushUp(pos);
}

void fun(ll pos, ll l, ll r, ll k)
{
    tag[pos] += k;
    ans[pos] += (r - l + 1) * k;
}

void pushDown(ll pos, ll l, ll r)
{
    ll mid = (l + r) / 2;
    fun(lc(pos), l, mid, tag[pos]);
    fun(rc(pos), mid + 1, r, tag[pos]);
    tag[pos] = 0;
}

void update(ll pos, ll nextl, ll nextr, ll l, ll r, ll k)
{
    // cout << "u " << pos << " " << nextl << " " << nextr <<  ' ' << l << " " << r << " " << k  << endl;
    if (nextl <= l && nextr >= r)
    {
        ans[pos] += k * (r - l + 1);
        tag[pos] += k;
        return;
    }
    pushDown(pos, l, r);
    ll mid = (l + r) / 2;
    if (nextl <= mid)
        update(lc(pos), nextl, nextr, l, mid, k);
    else
        update(rc(pos), nextl, nextr, mid + 1, r, k);
    pushUp(pos);
}

ll query(ll pos, ll nextl, ll nextr, ll l, ll r)
{
    ll res = 0;
    // cout << pos << " " << nextl << " " << nextr << " " << l << " " << r << " " << ans[pos] << endl;
    if (nextl <= l && nextr >= r)
        return ans[pos];
    pushDown(pos, l, r);
    ll mid = (l + r) / 2;
    if (nextl <= mid)
        res += query(lc(pos), nextl, nextr, l, mid);
    else
        res += query(rc(pos), nextl, nextr, mid + 1, r);
    return res;
}

ll qRange(ll node1, ll node2)
{
    ll res = 0;
    while (top[node1] != top[node2])
    {
        // cout << node1 << " " << node2 << endl;
        if (deep[top[node1]] < deep[top[node2]])
            swap(node1, node2);
        res += query(1, id[top[node1]], id[node1], 1, n);
        node1 = father[top[node1]];
    }
    if (deep[node1] > deep[node2])
        swap(node1, node2);
    res += query(1, id[node1], id[node2], 1, n);
    return res;
}

void updateTree(ll node, ll k)
{
    return update(1, id[node], id[node] + sons[node] - 1, 1, n, k);
}

void init()
{
    cin >> n >> m;
    for (ll i = 1; i <= n; i++)
        cin >> temp[i];
    for (ll i = 1; i < n; i++)
    {
        ll t1, t2;
        cin >> t1 >> t2;
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    dfs1(1, 0, 1);
    dfs2(1, 1);
    build(1, 1, n);
}

void work()
{
    while (m--)
    {
        ll opt, arg1, arg2;
        cin >> opt;
        if (opt == 1)
        {
            cin >> arg1 >> arg2;
            update(1, id[arg1], id[arg1], 1, n, arg2);
        }
        if (opt == 2)
        {
            cin >> arg1 >> arg2;
            updateTree(arg1, arg2);
        }
        if (opt == 3)
        {
            cin >> arg1;
            cout << qRange(arg1, 1) << endl;
        }
    }
}

int main()
{
    Buff;
    init();
    work();
    return 0;
}
2021/7/4 22:52
加载中...