zoukankan      html  css  js  c++  java
  • 国家集训队 旅游

    传送门

    好吧,是不是树剖板子做多了要挑战点难的……我们看看这道题吧!

    (好吧这题其实也就比板子难那么一点,至少给国集做是太简单了(^^))

    这道题就是代码特别长,好像咋写都要到5K左右。

    还是老套的树剖起手,这题其实唯一麻烦的地方在于他有一个全部取相反数的操作,这个我们可以打上一个rev标记。然后每次在下放的时候,下层的rev标记要^1,下层的权值要*-1,下层的最大最小值要先进行交换之后再*-1.然后合并答案的时候要同时维护权值,最大值和最小值。

    然后这题要把边权转化为点权,常规操作,我们把根(直接设成0就行)的点权赋为0,剩下的对于每一条边的边权都赋给它下面的第一个节点即可。不过这样的话在树剖沿链上调的时候LCA是不能计算在内的,这点需要注意一下。还有就是要注意这题是从0开始的,每次在单点修改也要下放标记。

    之后就没啥了……就是代码贼长还容易写错……

    看一下5K的代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #include<set>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 200005;
    const int mod = 1000000007;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,x,y,z,head[M],ecnt,dfn[M],hson[M],fa[M],top[M],idx,size[M],dep[M],ch[M],rk[M],m;
    char s[10];
    
    struct edge
    {
        int next,to,v;
    }e[M<<1];
    
    struct seg
    {
        int v,minn,maxn,rev;
    }t[M<<2];
    
    void add(int x,int y,int z)
    {
        e[++ecnt].to = y;
        e[ecnt].next = head[x];
        e[ecnt].v = z;
        head[x] = ecnt;
    }
    
    void dfs1(int x,int f,int depth)
    {
        size[x] = 1,fa[x] = f,dep[x] = depth;
        int maxson = -1;
        for(int i = head[x];i;i = e[i].next)
        {
        if(e[i].to == f) continue;
        ch[e[i].to] = e[i].v;
        dfs1(e[i].to,x,depth+1);
        size[x] += size[e[i].to];
        if(size[e[i].to] > maxson) maxson = size[e[i].to],hson[x] = e[i].to;
        }
    }
    
    void dfs2(int x,int t)
    {
        top[x] = t,dfn[x] = ++idx,rk[idx] = ch[x];
        if(!hson[x]) return;
        dfs2(hson[x],t);
        for(int i = head[x];i;i = e[i].next)
        {
        if(e[i].to == fa[x] || e[i].to == hson[x]) continue;
        dfs2(e[i].to,e[i].to);
        }
    }
    
    void update(int p)
    {
        t[p].v = t[p<<1].v + t[p<<1|1].v;
        t[p].maxn = max(t[p<<1].maxn,t[p<<1|1].maxn);
        t[p].minn = min(t[p<<1].minn,t[p<<1|1].minn);
    }
    
    void build(int p,int l,int r)
    {
        if(l == r)
        {
        t[p].v = t[p].minn = t[p].maxn = rk[l];
        return;
        }
        int mid = (l+r) >> 1;
        build(p<<1,l,mid),build(p<<1|1,mid+1,r);
        update(p);
    }
    
    void pushdown(int p,int l,int r)
    {
        t[p<<1].v *= -1,t[p<<1|1].v *= -1;
        t[p<<1].rev ^= 1,t[p<<1|1].rev ^= 1;
        swap(t[p<<1].minn,t[p<<1].maxn);
        swap(t[p<<1|1].minn,t[p<<1|1].maxn);
        t[p<<1].minn *= -1,t[p<<1].maxn *= -1;
        t[p<<1|1].minn *= -1,t[p<<1|1].maxn *= -1;
        t[p].rev = 0;
    }
    
    void modify(int p,int l,int r,int pos,int val)
    {
        if(l == r)
        {
        t[p].v = t[p].minn = t[p].maxn = val;
        return;
        }
        int mid = (l+r) >> 1;
        if(t[p].rev) pushdown(p,l,r);
        if(pos <= mid) modify(p<<1,l,mid,pos,val);
        else modify(p<<1|1,mid+1,r,pos,val);
        update(p);
    }
    
    void rever(int p,int l,int r,int kl,int kr)
    {
        if(l == kl && r == kr)
        {
        t[p].v *= -1,t[p].rev ^= 1;
        swap(t[p].minn,t[p].maxn);
        t[p].minn *= -1,t[p].maxn *= -1;
        return;
        }
        int mid = (l+r) >> 1;
        if(t[p].rev) pushdown(p,l,r);
        if(kr <= mid) rever(p<<1,l,mid,kl,kr);
        else if(kl > mid) rever(p<<1|1,mid+1,r,kl,kr);
        else rever(p<<1,l,mid,kl,mid),rever(p<<1|1,mid+1,r,mid+1,kr);
        update(p);
    }
    
    int query(int p,int l,int r,int kl,int kr,int flag)
    {
        if(l == kl && r == kr)
        {
        if(flag == 1) return t[p].v;
        if(flag == 2) return t[p].minn;
        if(flag == 3) return t[p].maxn;
        }
        int mid = (l+r) >> 1;
        if(t[p].rev) pushdown(p,l,r);
        if(kr <= mid) return query(p<<1,l,mid,kl,kr,flag);
        else if(kl > mid) return query(p<<1|1,mid+1,r,kl,kr,flag);
        else
        {
        int g1 = query(p<<1,l,mid,kl,mid,flag),g2 = query(p<<1|1,mid+1,r,mid+1,kr,flag);
        if(flag == 1) return g1 + g2;
        if(flag == 2) return min(g1,g2);
        if(flag == 3) return max(g1,g2);
        }
        update(p);
    }
    
    void rrange(int x,int y)
    {
        while(top[x] != top[y])
        {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        rever(1,1,n,dfn[top[x]],dfn[x]);
        x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        if(dfn[x] == dfn[y]) return;
        rever(1,1,n,dfn[x]+1,dfn[y]);
    }
    
    int srange(int x,int y)
    {
        int ans = 0;
        while(top[x] != top[y])
        {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        ans += query(1,1,n,dfn[top[x]],dfn[x],1);
        x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        if(dfn[x] == dfn[y]) return ans;
        ans += query(1,1,n,dfn[x]+1,dfn[y],1);
        return ans;
    }
    
    int maxrange(int x,int y)
    {
        int cur = -1000000009;
        while(top[x] != top[y])
        {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        cur = max(cur,query(1,1,n,dfn[top[x]],dfn[x],3));
        x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        if(dfn[x] == dfn[y]) return cur;
        cur = max(cur,query(1,1,n,dfn[x]+1,dfn[y],3));
        return cur;
    }
    
    int minrange(int x,int y)
    {
        int cur = 1000000009;
        while(top[x] != top[y])
        {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        cur = min(cur,query(1,1,n,dfn[top[x]],dfn[x],2));
        x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        if(dfn[x] == dfn[y]) return cur;
        cur = min(cur,query(1,1,n,dfn[x]+1,dfn[y],2));
        return cur;
    }
    
    int main()
    {
        n = read();
        rep(i,1,n-1) x = read(),y = read(),z = read(),add(x,y,z),add(y,x,z);
        dfs1(0,0,1),dfs2(0,0),build(1,1,n);
        m = read();
        while(m--)
        {
        scanf("%s",s);
        if(s[0] == 'C') x = read(),y = read(),modify(1,1,n,dfn[x],y);
        else if(s[0] == 'N') x = read(),y = read(),rrange(x,y);
        else if(s[0] == 'S') x = read(),y = read(),printf("%d
    ",srange(x,y));
        else if(s[1] == 'A') x = read(),y = read(),printf("%d
    ",maxrange(x,y));
        else x = read(),y = read(),printf("%d
    ",minrange(x,y));
        
        }
        return 0;
    }
  • 相关阅读:
    超详细JSON解析步骤
    HTTP请求头和响应头总结
    Oracle 数据库常用操作语句大全
    关于HTTP协议,一篇就够了
    PowerDesigner工具建表步骤
    求助:ACM剑气算法
    一道题
    个人Java学习中的遇到的几个模糊的地方
    Java编程:数学黑洞6174
    高级查询
  • 原文地址:https://www.cnblogs.com/captain1/p/9716527.html
Copyright © 2011-2022 走看看