zoukankan      html  css  js  c++  java
  • Problem E. TeaTree

    ps:对每个Value都开一个线段树,线段树的叶子节点的值表示的是这个Value的约数,什么意思呢?叶子节点的编号和Value的约数是一一对应的,然后区间维护最大值,是不是非常非常暴力,最后从底向上合并线段树(因为树的每个节点都开了一个线段树),注意要动态开点!!!

    官方题解:

    inline void upd(int &x, int y) { x < y && (x = y); }
    
    const int N = 100005;
    
    int n, tot, cnt;
    int head[N], ans[N], root[N], ls[400 * N], rs[400 * N], sum[400 * N];
    
    struct node { int to, next; } G[N];
    
    vector<int> d[N];
    
    void Inite() {
        cnt = tot = 0;
        mem(head, -1);
        for (int i = 1; i < N; ++i) for (int j = 1; i * j < N; ++j) d[i * j].pb(i);
    }
    
    void addedge(int u, int v) {
        G[tot].to = v, G[tot].next = head[u], head[u] = tot++;
    }
    
    void Pushup(int rt) {
        if (ls[rt] && rs[rt]) sum[rt] = max(sum[ls[rt]], sum[rs[rt]]);
        else if (ls[rt]) sum[rt] = sum[ls[rt]];
        else if (rs[rt]) sum[rt] = sum[rs[rt]];
    }
    
    int Merge(int x, int y, int& res) {
        if (!x || !y) return x ^ y;
        if (sum[x] == sum[y]) res = max(res, sum[x]);
        ls[x] = Merge(ls[x], ls[y], res);
        rs[x] = Merge(rs[x], rs[y], res);
        Pushup(x);
        return x;
    }
    
    void DFS(int u) {
        ans[u] = -1;
        for (int i = head[u]; ~i; i = G[i].next) {
            DFS(G[i].to);
            root[u] = Merge(root[u], root[G[i].to], ans[u]);
        }
    }
    
    void Update(int l, int r, int &rt, int pos) {
        if (!rt) rt = ++cnt;
        if (l == r) {
            sum[rt] = pos;
            return;
        }
        int mid = (l + r) >> 1;
        if (pos <= mid) Update(l, mid, ls[rt], pos);
        else Update(mid + 1, r, rs[rt], pos);
        Pushup(rt);
    }
    
    int main()
    {
        Inite();
    
        sc(n);
        Rep(i, 2, n) {
            int x;
            sc(x);
            addedge(x, i);
        }
    
        Rep(i, 1, n) {
            int x;
            sc(x);
            root[i] = 0;
            rep(j, 0, Size(d[x])) Update(1, N - 1, root[i], d[x][j]);
        }
    
        DFS(1);
        Rep(i, 1, n) pr(ans[i]);
    
        return 0;
    }
  • 相关阅读:
    Sql 字符串按指定字符转多行(表值函数)
    C# 默认打印机设置
    Sql server 触发器状态查询
    指定周转对应日期
    Java发送HttpRequest
    Java实现手机号码归属地判别
    MySQL导入.sql文件及常用命令
    解释和编译的区别
    Java中的static关键字解析
    内存堆和栈的区别
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9529267.html
Copyright © 2011-2022 走看看