zoukankan      html  css  js  c++  java
  • [codeforces]Codeforces Global Round 1 F. Nearest Leaf

    题解:  语文题????  上面说的一段代码 告诉你的是  节点编号顺序与dfs序顺序一致  也就是你  dfs序以后编号就是[1,n]  根据这个特性  那么我们只需要维护每个叶子节点到查询v的距离即可  那么我们只需要离线所有查询 然后对子树修改即可   用线段树来维护区间加和区间最小值就行

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=5e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    const ll inf=1e16;
    struct edge{int t;ll v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,ll vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    int num[MAXN];
    ll a[MAXN],sum[MAXN];
    bool vis[MAXN];
    void dfs(int x){
        num[x]=1;
        link(x){
    	sum[j->t]=sum[x]+j->v;
    	if(!vis[j->t])a[j->t]=sum[j->t];
    	else a[j->t]=inf;
    	dfs(j->t);
    	num[x]+=num[j->t];
        }
    }
    
    ll minn[MAXN<<2],flag[MAXN<<2];
    void push(int rt){
        if(flag[rt]){
    	flag[rt<<1]+=flag[rt];flag[rt<<1|1]+=flag[rt];
    	minn[rt<<1]+=flag[rt];minn[rt<<1|1]+=flag[rt];
    	flag[rt]=0;
        }
    }
    void up(int rt){minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);}
    void built(int rt,int l,int r){
        if(l==r){minn[rt]=a[l];return ;}
        int mid=(l+r)>>1;
        built(rt<<1,l,mid);
        built(rt<<1|1,mid+1,r);
        up(rt);
    }
    
    void update(int rt,int l,int r,int ql,int qr,ll k){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr){minn[rt]+=k;flag[rt]+=k;return ;}
        int mid=(l+r)>>1;
        push(rt);
        if(ql<=mid)update(rt<<1,l,mid,ql,qr,k);
        if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr,k);
        up(rt);
    }
    
    ll ans;
    void query(int rt,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){ans=min(ans,minn[rt]);return ;}
        int mid=(l+r)>>1;
        push(rt);
        if(ql<=mid)query(rt<<1,l,mid,ql,qr);
        if(qr>mid)query(rt<<1|1,mid+1,r,ql,qr);
        up(rt);
    }
    
    typedef struct node{
        int l,r,id;
    }node;
    vector<node>vec[MAXN];
    ll ans1[MAXN];
    int n;
    void dfs2(int x){
        for(int i=0;i<vec[x].size();i++){
    	ans=inf;query(1,1,n,vec[x][i].l,vec[x][i].r);
    	ans1[vec[x][i].id]=ans;
        }
        link(x){
    	int t=j->t;
    	update(1,1,n,t,t+num[t]-1,-(j->v));
    	update(1,1,n,1,t-1,j->v);
    	update(1,1,n,t+num[t],n,j->v);
    	dfs2(j->t);
    	update(1,1,n,t,t+num[t]-1,j->v);
    	update(1,1,n,1,t-1,-(j->v));
    	update(1,1,n,t+num[t],n,-(j->v));
        }
    }
    
    int main(){
        n=read();int q=read();
        int u;ll k;
        inc(i,2,n)u=read(),k=read(),add(u,i,k),vis[u]=1;
        a[1]=inf;dfs(1);
        built(1,1,n);
        int v,l,r;
        inc(i,1,q)v=read(),l=read(),r=read(),vec[v].pb((node){l,r,i});
        dfs2(1);
        inc(i,1,q)printf("%lld
    ",ans1[i]);
    }
    

      

  • 相关阅读:
    不使用循环使用递归得到数组的值得求和
    将int转int数组并将int数组元素处理后转int,实现加密
    小程序总结
    见过的最好的Layout讲解,挺全的
    (转)Java 的swing.GroupLayout布局管理器的使用方法和实例
    三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)
    二十六、Jcreator使用初步
    The Java™ Tutorials下载地址
    中间容器
    二十七、Java图形化界面设计——容器(JFrame)
  • 原文地址:https://www.cnblogs.com/wang9897/p/10355833.html
Copyright © 2011-2022 走看看