zoukankan      html  css  js  c++  java
  • SPOJ 375 QTREE

    题目链接:传送门

    题目大意:给一棵无根树,树边有权值,有很多次操作,QUERY代表询问从 x 到 y 路径上的边的最大

         权值,CHANGE代表改变按输入顺序第 x 条边的权值为 y。 对于每个QUERY,输出一个答案。

    题目思路:树链剖分(第一次学树链,还有点云里雾里的)

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <cctype>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    #define mst(x,y) memset(x,y,sizeof(x))
    #define mcp(x,y) memcpy(x,y,sizeof(y))
    using namespace std;
    #define gamma 0.5772156649015328606065120
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 10050
    #define maxn 30010
    typedef pair<int,int> PII;
    typedef long long LL;
    LL read(){
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m,k,head[N],hcnt,rt;
    char str[11];
    struct Node{
        int to,nxt,v;
    }node[maxn];
    struct Edge{
        int x,y,v;
    }edge[maxn];
    int seg[N<<2];
    
    int siz[N];  ///当前节点保存的儿子数
    int top[N];  ///当前节点所在链的顶端节点
    int son[N];  ///保存重儿子
    int dep[N];  ///当前节点深度
    int fa[N];   ///当前节点的父亲
    int id[N];   ///用来保存树中每个节点剖分后的新编号
    int posi[N]; ///在线段树中的位置
    int tid,pos;
    
    ///树链剖分
    void dfs1(int u,int f,int deep){ ///找重边
        dep[u]=deep;
        fa[u]=f;
        siz[u]=1;
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(e==f)continue;
            dfs1(e,u,deep+1);
            siz[u]+=siz[e];
            if(!son[u]||siz[son[u]]<siz[e])
                son[u]=e;
        }
    }
    void dfs2(int u,int tp){   ///连重边成重链
        top[u]=tp;
        id[u]=++tid;
        posi[id[u]]=u;
        if(!son[u])return;
        dfs2(son[u],tp);
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(e!=son[u]&&e!=fa[u])
                dfs2(e,e);
        }
    }
    
    ///线段树
    void build(int rt,int l,int r){
        seg[rt]=-inf;
        if(l==r) return;
        int mid=l+r>>1;
        build(lson); build(rson);
        seg[rt]=max(seg[rt<<1],seg[rt<<1|1]);
    }
    
    void add(int rt,int l,int r,int v){
        if(l==r){
            seg[rt]=v;
            return;
        }
        int mid=l+r>>1;
        if(pos<=mid)add(lson,v);
        else add(rson,v);
        seg[rt]=max(seg[rt<<1],seg[rt<<1|1]);
    }
    int query(int rt,int l,int r,int L,int R){
        if(L<=l&&r<=R){return seg[rt];}
        int mid=l+r>>1;
        int temp=INT_MIN;
        if(L<=mid)temp=max(temp,query(lson,L,R));
        if(R>mid) temp=max(temp,query(rson,L,R));
        return temp;
    }
    
    void ini(){
        mst(head,-1);hcnt=tid=0;mst(seg,0);
        mst(son,0);mst(siz,0);
    }
    void add(int x,int y,int v){
        node[hcnt].to=y,node[hcnt].nxt=head[x],node[hcnt].v=v,head[x]=hcnt++;
        node[hcnt].to=x,node[hcnt].nxt=head[y],node[hcnt].v=v,head[y]=hcnt++;
    }
    int lca(int x,int y){
        int ans=-inf;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans=max(ans,query(1,1,n,id[top[x]],id[x]));
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        if(x!=y)ans=max(ans,query(1,1,n,id[x]+1,id[y]));
        return ans;
    }
    int main(){
        //freopen("in.txt","r",stdin);
        int i,j,group,x,y,v,Case=0;
        group=read();
        while(group--){
            ini();
            n=read();
            for(i=1;i<n;++i){
                scanf("%d%d%d",&x,&y,&v);
                edge[i].x=x,edge[i].y=y,edge[i].v=v;
                add(x,y,v);
            }
            dfs1(1,1,1);
            dfs2(1,1);
            build(1,1,n);
            for(i=1;i<n;i++){
                if(dep[edge[i].x]<dep[edge[i].y])
                    swap(edge[i].x,edge[i].y);
                pos=id[edge[i].x];
                add(1,1,n,edge[i].v);
            }
            while(scanf("%s",str)!=EOF){
                if(str[0]=='D')break;
                x=read();y=read();
                if(str[0]=='Q'){
                    printf("%d
    ",lca(x,y));
                }
                else{
                    pos=id[edge[x].x];
                    add(1,1,n,y);
                }
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    day06 字典、元组、set的方法及常用操作
    python makestrans translate
    python 中locals() 和 globals()
    threading.local()
    进程 线程 协程
    微信机器人
    flask
    python is ==
    Beautiful Soup 4.4.0 基本使用方法
    12306
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5897411.html
Copyright © 2011-2022 走看看