【bzoj 1782】: [Usaco2010 Feb]slowdown 慢慢游

1782: [Usaco2010 Feb]slowdown 慢慢游

Time Limit: 1 Sec   Memory Limit: 64 MB
Submit: 559   Solved: 340
[ Submit][ Status]

Description

每天Farmer John的N头奶牛(1 <= N <= 100000,编号1…N)从粮仓走向他的自己的牧场。牧场构成了一棵树,粮仓在1号牧场。恰好有N-1条道路直接连接着牧场,使得牧场之间都恰好有一条路径相连。第i条路连接着A_i,B_i,(1 <= A_i <= N; 1 <= B_i <= N)。奶牛们每人有一个私人牧场P_i (1 <= P_i <= N)。粮仓的门每次只能让一只奶牛离开。耐心的奶牛们会等到他们的前面的朋友们到达了自己的私人牧场后才离开。首先奶牛1离开,前往P_1;然后是奶牛2,以此类推。当奶牛i走向牧场P_i时候,他可能会经过正在吃草的同伴旁。当路过已经有奶牛的牧场时,奶牛i会放慢自己的速度,防止打扰他的朋友。 考虑如下的牧场结构(括号内的数字代表了 牧场的所有者)。 


Input

* 第1行 : 一个正整数N * 第2…N行: 第i+1行包括一对正整数A_i,B_i * 第N+1..N+N行: 第 N+i行 包括一个正整数: P_i

Output

* 第一行到第N行:第i行表示第i只奶牛需要被放慢的次数

Sample Input

5
1 4
5 4
1 3
2 4
4
2
1
5
3

Sample Output

0
1
0
2
1


查询某个节点的答案
就是看它到根节点有多少个比它小
所以按值建立树状数组,维护dfs序


//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive
************************************************/
/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
/
const int N=100010;
int n;
struct edge{int v,next;}e[N*2];
int head[N],k;

int ans[N],id[N];
int c[N];
/
inline int lowbit(int x){return x&-x;}
void add(int id,int x){for(;id<=n;id+=lowbit(id))c[id]+=x;}
int query(int id){int res=0;for(;id>0;id-=lowbit(id))res+=c[id];return res;}
void adde(int u,int v){e[k].v=v;e[k].next=head[u];head[u]=k++;}
inline int getint()
{
      int res=0;char c=getchar();
      while(!isdigit(c))c=getchar();
      while(isdigit(c))res=res*10+c-'0',c=getchar();
      return res;
}
void dfs(int u,int fa)
{
    ans[id[u]]=query(id[u]);
    add(id[u],1);
    INE(i,u,e)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);
    }
    add(id[u],-1);
}
/
void input()
{
    MS(head,-1);
    n=getint();
    int u,v;
    rep(i,1,n-1) u=getint(),v=getint(),adde(u,v),adde(v,u);
    rep(i,1,n) id[getint()]=i;
}
void solve()
{
    ///init///
    
    calculate
    dfs(1,-1);
    /output/
    rep(i,1,n) printf("%d\n",ans[i]);
}
/
int main()
{
    #ifndef _TEST
    freopen("std.in","r",stdin); freopen("std.out","w",stdout);
    #endif
    input();
    solve();
    #ifdef _TEST
    for(;;);
    #endif
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值