zoukankan      html  css  js  c++  java
  • wannafly挑战赛4树的距离 离线处理,dfs序

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    wyf非常喜欢树。一棵有根数树上有N个节点,1号点是他的根,每条边都有一个距离,而wyf是个爱问奇怪问题的熊孩子,他想知道对于某个点x,以x为根的子树上,所有与x距离大于等于k的点与x的距离之和。

    输入描述:

    第一行一个正整数N

    接下来N-1描述这棵树,每行两个数第i行两个数p和D表示树上有一条p到i+1长度为D的边。(p<=i)

    下面一行一个正整数Q表示wyf的询问次数。

    接下来Q行每行两个正整数x和k。 (1<=N,Q<=2x105,1<=D,K<=106)

    输出描述:

    对于每次询问x,k输出以x为根的子树上,所有与x距离大于等于k的点与x的距离之和。(若不存在这样的点,则输出应为0)
    示例1

    输入

    3
    1 2
    1 3
    2
    1 3
    1 2

    输出

    3
    5
    
    
    


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+88;
    long long ans[N];
    int tot,head[N],pos[N],kt,lt[N];
    struct cta{
     int next,to,w;
    }e[N<<1];
    struct node{
     int num,l,r;
     long long sum;
    }tr[N<<2];
    struct qqq{
     int id,rto;
     long long k;
     bool operator <(const qqq &A)const{
     return k>A.k;
     }
    }qt[N];
    struct ttt{
     long long dis;
     int id;
     bool operator < (const ttt &B)const{
       return dis>B.dis;
     }
    }dt[N];
    void add(int u,int v,int w) {
     e[tot].to=v;e[tot].next=head[u];e[tot].w=w;head[u]=tot++;
    }
    void build(int l,int r,int rt){
     tr[rt].l=l,tr[rt].r=r;
     tr[rt].sum=tr[rt].num=0;
     if(l==r) return;
     int mid=(l+r)>>1;
     build(l,mid,rt<<1);
     build(mid+1,r,rt<<1|1);
    }
    void dfs(int u,long long now,int f){
     pos[u]=++kt;
     for(int i=head[u];~i;i=e[i].next)  {
     if(e[i].to==f) continue;
     else dfs(e[i].to,dt[e[i].to].dis=e[i].w+now,u);
     }
     lt[u]=kt;
    }
    void modify(int pos,int rt,int cc){
     int l=tr[rt].l,r=tr[rt].r;
     int mid=(l+r)>>1;
     if(l==r) {
      tr[rt].num=1;
      tr[rt].sum+=dt[cc].dis;
         return;}
     if(pos<=mid) modify(pos,rt<<1,cc);
     else modify(pos,rt<<1|1,cc);
     tr[rt].num=tr[rt<<1].num+tr[rt<<1|1].num;
     tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
    }
    long long query(int L,int R,int rt,long long &cty){
     long long now=0;
     if(L>R) return 0;
     int l=tr[rt].l,r=tr[rt].r;
     if(L<=l&&R>=r) {cty+=tr[rt].num; return tr[rt].sum;}
     int mid=(l+r)>>1;
     if(mid>=L) now+=query(L,R,rt<<1,cty);
     if(mid<R) now+=query(L,R,rt<<1|1,cty);
     return now;
    }
    int tran[N];
    int main(){
     int n,x,y,m;
     memset(head,-1,sizeof(head));
     tot=kt=0;
     scanf("%d",&n);
     build(1,n,1);
     for(int i=2;i<=n;++i) {
      scanf("%d%d",&x,&y);
      add(x,i,y);
      add(i,x,y);
     }
     dfs(1,0,0);
     for(int i=1;i<=n;++i) dt[i].id=i;
     scanf("%d",&m);
     for(int i=1;i<=m;++i) {
      scanf("%d%lld",&qt[i].rto,&qt[i].k);
      qt[i].id=i;
      qt[i].k+=dt[qt[i].rto].dis;
     }
     sort(qt+1,qt+1+m);
     sort(dt+1,dt+n+1);
     int r=1;
     for(int i=1;i<=n;++i) tran[dt[i].id]=i;
     for(int i=1;i<=m;++i) {
         long long now=0;
         for(;r<=n;++r) if(!(dt[r].dis>=qt[i].k)) break;else modify(pos[dt[r].id],1,r);
         ans[qt[i].id]=query(pos[qt[i].rto]+1,lt[qt[i].rto],1,now);
         ans[qt[i].id]-=now*dt[tran[qt[i].rto]].dis;
     }
     for(int i=1;i<=m;++i) printf("%lld ",ans[i]);
    }
    
    
  • 相关阅读:
    ES6基础之——对象表达式
    ES6基础之——函数的名字name属性
    ES6基础之——解构参数 Destructured Parameters
    ES6基础之——展开操作符Spread和剩余操作符Rest
    ES6基础之——箭头函数Arrow Fuctions
    ES6基础——默认参数 Default Parameter Values
    node.js 调用第三方服务
    node 创建server 及加载静态页面
    VUE插件-图片濑加载
    Less函数说明
  • 原文地址:https://www.cnblogs.com/mfys/p/7911129.html
Copyright © 2011-2022 走看看