zoukankan      html  css  js  c++  java
  • [USACO12DEC]逃跑的BarnRunning Away From…

    题意

    给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个

    题解

    似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子……

    调了一个上午一直WA……狠下心来重打一遍居然直接一遍过……

    先dfs一遍,把到根节点的距离算出来,然后建出树上的主席树

    然后考虑,$d[v]-d[u]<=L$,$d[v]<=L+d[u]$

    然后就是对于每一个$d[u]+L$查询一下区间内有多少比它小的就好

    细节问题:因为不能保证$d[u]+L$在离散化后的数组内存在,所以要用upper_bound,并查询比它小的,而且要在离散化的数组后面加一个inf

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define N 200005
     4 #define M 4000005
     5 #define ll long long
     6 #define inf 0x3f3f3f3f
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline ll read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;ll res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 char obuf[1<<24],*o=obuf;
    21 void print(int x){
    22     if(x>9) print(x/10);
    23     *o++=x%10+48;
    24 }
    25 int sum[M],L[M],R[M],rt[N];
    26 int ver[N<<1],Next[N<<1],head[N];ll edge[N<<1];
    27 int ls[N],rs[N];ll a[N],b[N];
    28 int n,m,cnt,tot;ll p;
    29 void update(int last,int &now,int l,int r,int x){
    30     sum[now=++cnt]=sum[last]+1;
    31     if(l==r) return;
    32     int mid=(l+r)>>1;
    33     if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
    34     else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
    35 }
    36 int query(int u,int v,int l,int r,int k){
    37     if(r<k) return sum[v]-sum[u];
    38     if(l>=k) return 0;
    39     int mid=(l+r)>>1;
    40     if(k<=mid) return query(L[u],L[v],l,mid,k);
    41     else return query(R[u],R[v],mid+1,r,k)+sum[L[v]]-sum[L[u]];
    42 }
    43 inline void add(int u,int v,ll e){
    44     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
    45 }
    46 void dfs(int u,int fa,ll d){
    47     b[ls[u]=++m]=d,a[m]=d;
    48     for(int i=head[u];i;i=Next[i])
    49     if(ver[i]!=fa) dfs(ver[i],u,d+edge[i]);
    50     rs[u]=m;
    51 }
    52 int main(){
    53     n=read(),p=read();
    54     for(int u=2;u<=n;++u){
    55         int v=read();ll e=read();
    56         add(v,u,e);
    57     }
    58     dfs(1,0,0);
    59     sort(b+1,b+1+m);
    60     m=unique(b+1,b+1+m)-b-1;
    61     for(int i=1;i<=n;++i){
    62         int k=lower_bound(b+1,b+1+m,a[i])-b;
    63         update(rt[i-1],rt[i],1,m,k);
    64     }
    65     b[m+1]=inf;
    66     for(int i=1;i<=n;++i){
    67         int k=upper_bound(b+1,b+2+m,a[ls[i]]+p)-b;
    68         k=query(rt[ls[i]-1],rt[rs[i]],1,m,k);
    69         print(k);
    70         *o++='
    ';
    71     }
    72     fwrite(obuf,o-obuf,1,stdout);
    73     return 0;
    74 }
  • 相关阅读:
    【SQLSERVER】动态游标的实现
    【Oracle】动态游标的实现
    【SQLSERVER】拷贝表数据
    LeetCode: Count and Say
    LeetCode: Construct Binary Tree from Preorder and Inorder Traversa
    LeetCode: Combinations
    LeetCode: Convert Sorted List to Binary Search Tree
    LeetCode: Decode Ways
    LeetCode: Combination Sum II
    LeetCode: Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9395186.html
Copyright © 2011-2022 走看看