• 省选测试45


    A 求和 (Unaccepted)

    题目大意 :

    Code

    Show Code

    B 农民

    题目大意 : 一颗二叉树,每个点左子树中的点只有点权比这个点小的才可能得到肥,右子树相反,修改一个点的点权,或翻转一个子树内所有点的左右儿子,询问一个点是否有肥

    • 考虑一条向左的边会对这个子树内所有点产生一个最大值的限制,向右的相反,所以查询一个点的时候就看从这个点到跟这条链上所有的限制是否都能满足

    • 所以线段树分别维护最大最小值限制的最大最小值,单点修改,翻转的时候就区间翻,把最大最小值的限制反过来就行

    Code

    Show Code
    #include <cstdio>
    #include <algorithm>
    #define ls (rt << 1)
    #define rs (rt << 1 | 1)
    #define Get(x) (ch[fa[x]][1] == x)
    
    using namespace std;
    const int N = 1e5 + 5;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    
    bool v[N], tag[N*4];
    int n, m, a[N], ch[N][2], rt;
    int son[N], sz[N], fa[N], tp[N], dep[N], dfn[N], dfc, rk[N];
    
    void Dfs(int x) {
        dep[x] = dep[fa[x]] + 1; sz[x] = 1;
        for (int i = 0, y; i <= 1; ++i) {
            if (!(y = ch[x][i])) continue;
            fa[y] = x; Dfs(y); sz[x] += sz[y];
            if (sz[son[x]] < sz[y]) son[x] = y;
        }
    }
    
    void Dfs(int x, int top) {
        tp[x] = top; dfn[x] = ++dfc; rk[dfc] = x;
        if (son[x]) Dfs(son[x], top);
        for (int i = 0, y; i <= 1; ++i)
            if ((y = ch[x][i]) && y != son[x]) Dfs(y, y);
    }
    
    struct Tree {
        int dl, xl, dr, xr;
    }t[N*4];
    
    Tree operator + (const Tree &a, const Tree &b) {
        Tree c = a;
        if (!c.dl) c.dl = b.dl, c.xl = b.xl;
        else if (b.dl) c.dl = max(c.dl, b.dl), c.xl = min(c.xl, b.xl);
        if (!c.dr) c.dr = b.dr, c.xr = b.xr;
        else if (b.dr) c.dr = max(c.dr, b.dr), c.xr = min(c.xr, b.xr);
        return c;
    }
    
    void Update(int rt) {
        tag[rt] ^= 1;
        swap(t[rt].dl, t[rt].dr); 
        swap(t[rt].xl, t[rt].xr);
    }
    
    void Pushdown(int rt) {
        if (!tag[rt]) return; 
        tag[rt] = 0; Update(ls); Update(rs);
    }
    
    void Build(int rt, int l, int r) {
        if (l == r) {
            if (Get(rk[l])) t[rt].dl = t[rt].xl = a[fa[rk[l]]];
            else t[rt].dr = t[rt].xr = a[fa[rk[l]]];
            return;
        }
        int mid = l + r >> 1;
        Build(ls, l, mid); Build(rs, mid+1, r);
        t[rt] = t[ls] + t[rs];
    }
    
    void Modify(int rt, int l, int r, int x) {
        if (l == r) {
            if (t[rt].dl) t[rt].dl = t[rt].xl = a[fa[rk[l]]];
            else t[rt].dr = t[rt].xr = a[fa[rk[l]]];
            return;
        }
        int mid = l + r >> 1; Pushdown(rt);
        if (x <= mid) Modify(ls, l, mid, x);
        else Modify(rs, mid + 1, r, x);
        t[rt] = t[ls] + t[rs];
    }
    
    void Reverse(int rt, int l, int r, int x, int y) {
        if (x <= l && r <= y) return Update(rt);
        int mid = l + r >> 1; Pushdown(rt);
        if (x <= mid) Reverse(ls, l, mid, x, y);
        if (y >  mid) Reverse(rs,mid+1,r, x, y);
        t[rt] = t[ls] + t[rs];
    }
    
    Tree Ask(int rt, int l, int r, int x, int y) {
        if (x <= l && r <= y) return t[rt];
        int mid = l + r >> 1; Pushdown(rt);
        Tree ans = (Tree) {0, 0, 0, 0};
        if (x <= mid) ans = ans + Ask(ls, l, mid, x, y);
        if (y >  mid) ans = ans + Ask(rs,mid+1,r, x, y);
        return ans;
    }
    
    int main() {
        //freopen("IN", "r", stdin);
        freopen("farmer.in", "r", stdin);
        freopen("farmer.out", "w", stdout);
        n = read(); m = read();
        for (int i = 1; i <= n; ++i) {
            a[i] = read(); 
            ch[i][0] = read(); ch[i][1] = read();
            v[ch[i][0]] = v[ch[i][1]] = 1;
        }
        for (int i = 1; i <= n; ++i)
            if (!v[i]) rt = i;
        Dfs(rt); Dfs(rt, rt); Build(1, 1, n);
        while (m--) {
            int od = read(), x = read();
            if (od == 1) {
                a[x] = read();
                if (ch[x][0]) Modify(1, 1, n, dfn[ch[x][0]]);
                if (ch[x][1]) Modify(1, 1, n, dfn[ch[x][1]]);
            }
            else if (od == 2) {
                int l = dfn[x] + 1, r = dfn[x] + sz[x] - 1;
                if (l <= r) Reverse(1, 1, n, l, r);
            }
            else {
                int w = a[x]; Tree ans = (Tree) {0, 0, 0, 0};
                while (tp[x] != 1)
                    ans = ans + Ask(1, 1, n, dfn[tp[x]], dfn[x]), x = fa[tp[x]];
                if (dfn[x] != 1) ans = ans + Ask(1, 1, n, 2, dfn[x]);
                puts(w > ans.dl && (w < ans.xr || !ans.xr) ? "YES" : "NO");
            }
        }
        return 0;
    }
    

    C 仙人掌

    题目大意 :

    Code

    Show Code
  • 相关阅读:
    php类自动加载
    tp5自定义分页参数
    cURL error 60: SSL certificate problem...
    ajax动态刷新的元素,导致绑定事件失效
    thinkphp5省市区三级联动例子
    restful状态码常用
    mysql的like子句
    mysql官方的测试数据库employees超30万的数据,安装方法介绍
    Aes加解密,php
    php5.6,Ajax报错,Warning: Cannot modify header information
  • 原文地址:https://www.cnblogs.com/shawk/p/14565496.html
Copyright © 2020-2023  润新知