zoukankan      html  css  js  c++  java
  • ural1553 Caves and Tunnels

    Caves and Tunnels

    Time limit: 3.0 second
    Memory limit: 64 MB
    After landing on Mars surface, scientists found a strange system of caves connected by tunnels. So they began to research it using remote controlled robots. It was found out that there exists exactly one route between every pair of caves. But then scientists faced a particular problem. Sometimes in the caves faint explosions happen. They cause emission of radioactive isotopes and increase radiation level in the cave. Unfortunately robots don't stand radiation well. But for the research purposes they must travel from one cave to another. So scientists placed sensors in every cave to monitor radiation level in the caves. And now every time they move robots they want to know the maximal radiation level the robot will have to face during its relocation. So they asked you to write a program that will solve their problem.

    Input

    The first line of the input contains one integer N (1 ≤ N ≤ 100000) — the number of caves. NextN − 1 lines describe tunnels. Each of these lines contains a pair of integers aibi(1 ≤ aibi ≤ N) specifying the numbers of the caves connected by corresponding tunnel. The next line has an integer Q (Q ≤ 100000) representing the number of queries. The Q queries follow on a single line each. Every query has a form of "C U V", where C is a single character and can be either 'I' or 'G' representing the type of the query (quotes for clarity only). In the case of an 'I' query radiation level in U-th cave (1 ≤ U ≤ N) is incremented by V (0 ≤ V ≤ 10000). In the case of a 'G' query your program must output the maximal level of radiation on the way between caves with numbers U and V (1 ≤ UV ≤ N) after all increases of radiation ('I' queries) specified before current query. It is assumed that initially radiation level is 0 in all caves, and it never decreases with time (because isotopes' half-life time is much larger than the time of observations).

    Output

    For every 'G' query output one line containing the maximal radiation level by itself.

    Sample

    inputoutput
    4
    1 2
    2 3
    2 4
    6
    I 1 1
    G 1 1
    G 3 4
    I 2 3
    G 1 1
    G 3 4 
    
    1
    0
    1
    3
    

    分析:树上点修改+区间极值查询,树链剖分;

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10,mod=1e9+7,inf=0x3f3f3f3f;
    int n,m,k,t,tot;
    int bl[maxn],pos[maxn],dep[maxn],sz[maxn],fa[maxn];
    int mx[maxn<<2];
    vector<int>e[maxn];
    void dfs(int x,int y=0)
    {
        sz[x]=1;
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(z==y)continue;
            fa[z]=x;dep[z]=dep[x]+1;
            dfs(z,x);
            sz[x]+=sz[z];
        }
    }
    void dfs1(int x,int chain)
    {
        bl[x]=chain;
        pos[x]=++tot;
        int big=0;
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(dep[z]<dep[x])continue;
            if(sz[z]>sz[big])big=z;
        }
        if(!big)return;
        dfs1(big,chain);
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(dep[z]<dep[x]||z==big)continue;
            dfs1(z,z);
        }
    }
    void pup(int rt){mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);}
    void upd(int x,int y,int l,int r,int rt)
    {
        if(x==l&&x==r){mx[rt]+=y;return;}
        int mid=l+r>>1;
        if(x<=mid)upd(x,y,l,mid,rt<<1);
        else upd(x,y,mid+1,r,rt<<1|1);
        pup(rt);
    }
    int q(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return mx[rt];
        int mid=l+r>>1;
        int ret=0;
        if(L<=mid)ret=max(ret,q(L,R,l,mid,rt<<1));
        if(mid+1<=R)ret=max(ret,q(L,R,mid+1,r,rt<<1|1));
        return ret;
    }
    int main()
    {
        int i,j;
        //freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            e[x].push_back(y);
            e[y].push_back(x);
        }
        dfs(1);
        dfs1(1,1);
        scanf("%d",&m);
        while(m--)
        {
            char op[2];
            int x,y;
            scanf("%s%d%d",op,&x,&y);
            if(op[0]=='I')upd(pos[x],y,1,n,1);
            else
            {
                int ret=0;
                while(bl[x]!=bl[y])
                {
                    if(dep[bl[x]]<dep[bl[y]])swap(x,y);
                    ret=max(ret,q(pos[bl[x]],pos[x],1,n,1));
                    x=fa[bl[x]];
                }
                if(pos[x]>pos[y])swap(x,y);
                ret=max(ret,q(pos[x],pos[y],1,n,1));
                printf("%d
    ",ret);
            }
        }
        return 0;
    }
  • 相关阅读:
    写给大忙人的spring cloud 1.x学习指南
    spring boot 1.x完整学习指南(含各种常见问题servlet、web.xml、maven打包,spring mvc差别及解决方法)
    Spring-Data-Redis下实现redis连接断开后自动重连(真正解决)
    写给大忙人的nginx核心配置详解(匹配&重写、集群、环境变量&上下文、Lua)
    javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 解决方法
    linux下配置nginx使用ftp目录作为静态资源文件的目标目录
    写给大忙人的centos下ftp服务器搭建(以及启动失败/XFTP客户端一直提示“用户身份验证失败”解决方法)
    linux下mysql 8.0安装
    写给大忙人的Elasticsearch架构与概念(未完待续)
    写给大忙人的ELK最新版6.2.4学习笔记-Logstash和Filebeat解析(java异常堆栈下多行日志配置支持)
  • 原文地址:https://www.cnblogs.com/dyzll/p/5838062.html
Copyright © 2011-2022 走看看