zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 沈阳赛区网络预赛

    J. Ka Chang

    昨天学弟写的,感觉题目挺好的,今天写了写。

    和以前分块一样,但这题很难想到用分块做。

    像是一次操作大量的区间单点修改,区间查询……

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 5;
    int cnt[205][maxn];
    ll val[maxn];
    vector<int> g[maxn];
    int ord[maxn];
    int L[maxn], R[maxn], depth[maxn];
    int ind = 0;
    void dfs(int u, int fa, int dep)
    {
        L[u] = ++ind;
        ord[ind] = u;
        depth[ind] = dep;
        for(int i = 0; i < g[u].size(); i++)
        {
            int v = g[u][i];
            if(v == fa) continue;
            dfs(v, u, dep + 1);
        }
        R[u] = ind;
    }
    int posl[205], posr[205];
    int pos[maxn];
    ll sum[205];
    int t = 0;
    void change(int dep,int x)
    {
        val[dep] += (ll)x;
        for(int i = 1; i <= t; i++)
        {
            sum[i] += (ll)x * cnt[i][dep];
        }
    }
    ll query(int l, int r)
    {
        int p = pos[l], q = pos[r];
        ll ans = 0;
        if(p == q)
        {
            for(int i = l; i <= r; i++)
            {
                ans += val[depth[i]];
            }
        }
        else
        {
            for(int i = p + 1; i <= q - 1; i++)
            {
                ans += sum[i];
            }
            for(int i = l; i <= posr[p]; i++)
            {
                ans += val[depth[i]];
            }
            for(int i = posl[q]; i <= r; i++)
            {
                ans += val[depth[i]];
            }
        }
        return ans;
    }
    int main()
    {
        int n, q; scanf("%d %d", &n, &q);
        for(int i = 1; i <= n - 1; i++)
        {
            int u, v; scanf("%d %d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, -1, 0);
        t = min(200, (int)sqrt(n));
        int len = n / t;
        for(int i = 1; i <= t; i++)
        {
            posl[i] = (i - 1) * len + 1;
            posr[i] = i * len;
        }
        if(posr[t] < n) t++, L[t] = R[t - 1] + 1, R[t] = n;
        ///预处理
        for(int i = 1; i <= t; i++)
        {
            for(int j = posl[i]; j <= posr[i]; j++)
            {
                pos[j] = i;
                cnt[i][depth[j]]++;
            }
        }
        while(q--)
        {
            int op, l, x;
            scanf("%d", &op);
            if(op == 1)
            {
                scanf("%d %d", &l, &x);
                change(l, x);
            }
            else
            {
                scanf("%d", &x);
                printf("%lld
    ", query(L[x], R[x]));
            }
        }
        return 0;
    }
    Code
  • 相关阅读:
    Android开发环境
    安卓学习
    Shuffle'm Up POJ
    Duizi and Shunzi HDU
    Find a path HDU
    Cyclic Nacklace HDU
    Keywords Search HDU
    HDU 1495 非常可乐
    J
    Fire Game FZU
  • 原文地址:https://www.cnblogs.com/littlepear/p/9612728.html
Copyright © 2011-2022 走看看