• Zijian-lv #3 树句节狗提


    如你所见,这是一道狗题

    一棵树,多次询问与一个点距离至少为 $k$ 的点的权值和

    $n,q leq 2525010$

    sol:

    长链剖分

    需要注意的是这道题卡空间

    我把我所有的 vector 换成链表才过了

    #include <bits/stdc++.h>
    #define LL long long
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch;
        for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 2525015;
    int n, q, lim;/*
    vector<pair<int, int> > qs[maxn];
    vector<int> G[maxn];*/
    int qcd[maxn];
    struct Chain {
        int head[maxn], nx[maxn], id[maxn], sz;
        Chain() {memset(head, 0, sizeof(head)); sz = 0;}
        inline void AddItem(int pos, int Item, int other = -1) {
            id[++sz] = Item;
            nx[sz] = head[pos];
            head[pos] = sz;
            if(~other) qcd[sz] = other;
        }
    }qs, G;
    LL ans[maxn], pool[maxn], *f[maxn], *now=pool+1;
    int a[maxn];
    void print(int q, LL* ans, int lim) {
        LL res; 
        for(int i = 1; i <= q; ) {
            res = 0;
            for(int j = i; j <= min(q, i + lim - 1); j++) res ^= ans[j];
            i += lim;
            printf("%lld
    ", res);
        }
        return ;
    }
    int mxs[maxn], mxd[maxn];
    void dfs(int x) {
        mxd[x] = 0;
        for(int i=G.head[x];i;i=G.nx[i]) {
            dfs(G.id[i]);
            mxd[x] = max(mxd[x], mxd[G.id[i]] + 1);
            if((mxd[G.id[i]] > mxd[mxs[x]])) mxs[x] = G.id[i];
        }
    }
    void solve(int x) {
        if(mxs[x]) {
            f[mxs[x]] = f[x] + 1;
            solve(mxs[x]);
        }
        f[x][0] = a[x];
        for(int i=G.head[x];i;i=G.nx[i]) {
            if(G.id[i] == mxs[x]) continue;
            f[G.id[i]] = now; now += mxd[G.id[i]] + 1; solve(G.id[i]);
            rep(j, 0, mxd[G.id[i]]) f[x][j+1] += f[G.id[i]][j];
            //cout << "to: " << to << " " << f[x][1] << endl; 
        }
        //cout << x << " " << f[x][1] << endl;
        /*dwn(i, mxd[x]-1, 0) {
            cout << f[x][i] << " jiale " << f[x][i + 1] << endl;
            f[x][i] += f[x][i + 1];
        }*/
        f[x][0] += f[x][1];
        for(int i=qs.head[x];i;i=qs.nx[i]) {
            if(qs.id[i] > mxd[x]) ans[qcd[i]] = 0;
            else ans[qcd[i]] = f[x][qs.id[i]];
        }/*
        if(qs[x].size()) {
        //    cout << "DEBUG: " << qs[x].first << " " << qs[x].second << " " << f[x][qs[x].first] << endl;
        //    if(qs[x].first > mxd[x]) ans[qs[x].second] = 0;
        //    else
            /*cout << "x: " << x << endl;
            rep(i, 0, mxd[x])
                cout << f[x][i] << " ";
            cout << endl;*/
        /*    
            for(auto ii : qs[x]) {
                //cout << "DEBUG: " << ii.first << " " << mxd[x] << endl;
                if(ii.first > mxd[x]) ans[ii.second] = 0;
                else ans[ii.second] = f[x][ii.first];
            }
        }*/
    }
    int main() {
        n = read(); int x, y;
        rep(i, 1, n) a[i] = read();
        rep(i, 2, n) {
            //x = read(), G[x].push_back(i);
            x = read();
            G.AddItem(x, i);
        }
        q = read();
        rep(i, 1, q) {
            x = read(); y = read();
            //qs[x].push_back(make_pair(y, i));
            qs.AddItem(x, y, i);
        } mxd[0] = -1;
        dfs(1);
        f[1] = now; now += mxd[1] + 1; solve(1);
        lim = read();
        print(q, ans, lim);
        //rep(i, 1, q) cout << ans[i] << endl;
    }
    View Code

     论我的没 log 跑得没别人带 log 快

  • 相关阅读:
    CXB 闯关游戏
    CXB 移动“哨兵棋子”
    GHOJ 300 Hanoi塔
    攻防世界 web 进阶区 刷题记录
    攻防世界 web 新手练习 刷题记录
    TensorFlow01:增加变量显示+tensorboard可视化
    TensorFlow01:梯度下降
    TensorFlow01:张量
    01深度学习介绍
    05Python爬虫:响应内容写入文件
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10518200.html
Copyright © 2020-2023  润新知