zoukankan      html  css  js  c++  java
  • 洛谷P2982 [USACO10FEB]慢下来Slowing down [2017年四月计划 树状数组01]

    P2982 [USACO10FEB]慢下来Slowing down

    题目描述

    Every day each of Farmer John's N (1 <= N <= 100,000) cows conveniently numbered 1..N move from the barn to her private pasture. The pastures are organized as a tree, with the barn being on pasture 1. Exactly N-1 cow unidirectional paths connect the pastures; directly connected pastures have exactly one path. Path i connects pastures A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N).

    Cow i has a private pasture P_i (1 <= P_i <= N). The barn's small door lets only one cow exit at a time; and the patient cows wait until their predecessor arrives at her private pasture. First cow 1 exits and moves to pasture P_1. Then cow 2 exits and goes to pasture P_2, and so on.

    While cow i walks to P_i she might or might not pass through a pasture that already contains an eating cow. When a cow is present in a pasture, cow i walks slower than usual to prevent annoying her friend.

    
    Consider the following pasture network, where the number between
    parentheses indicates the pastures' owner.
    
            1 (3)        
           / 
      (1) 4   3 (5)
         /    
    (2) 2   5 (4)
    
    First, cow 1 walks to her pasture:
    
            1 (3)        
           / 
      [1] 4*  3 (5)
         /    
    (2) 2   5 (4)
    
    When cow 2 moves to her pasture, she first passes into the barn's
    pasture, pasture 1. Then she sneaks around cow 1 in pasture 4 before
    arriving at her own pasture.
    
            1 (3)
           / 
      [1] 4*  3 (5)
         /    
    [2] 2*  5 (4)
    
    Cow 3 doesn't get far at all -- she lounges in the barn's pasture, #1.
    
            1* [3]
           / 
      [1] 4*  3 (5)
         /    
    [2] 2*  5 (4)
    
    Cow 4 must slow for pasture 1 and 4 on her way to pasture 5:
    
            1* [3]
           / 
      [1] 4*  3 (5)
         /    
    [2] 2*  5* [4]
    
    Cow 5 slows for cow 3 in pasture 1 and then enters her own private pasture:
    
            1* [3]
           / 
      [1] 4*  3*[5]
         /    
    [2] 2*  5* [4]

    FJ would like to know how many times each cow has to slow down.

    每天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会放慢自己的速度,防止打扰他的朋友。

    FJ想要知道奶牛们总共要放慢多少次速度。

    输入输出格式

    输入格式:

    • Line 1: Line 1 contains a single integer: N

    • Lines 2..N: Line i+1 contains two space-separated integers: A_i and B_i

    • Lines N+1..N+N: line N+i contains a single integer: P_i

    输出格式:

    • Lines 1..N: Line i contains the number of times cow i has to slow down.

    输入输出样例

    输入样例#1:
    5 
    1 4 
    5 4 
    1 3 
    2 4 
    4 
    2 
    1 
    5 
    3 

    //题解在后面
    #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #define max(a,b) ((a) > (b) ? (a) : (b)) #define min(a,b) ((a) > (b) ? (b) : (a)) #define lowbit(a) ((a) & (-(a))) int read() { int x = 0;char ch = getchar();char c = ch; while(ch > '9' || ch < '0')c = ch, ch = getchar(); while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); if(c == '-')return -x; return x; } const int INF = 0x3f3f3f3f; const int MAXN = 1000000 + 10; int n,muchang[MAXN],ans[MAXN],head[MAXN],cnt,step,data[MAXN]; bool b[MAXN]; struct Edge{int u,v,next;}edge[MAXN]; void insert(int a,int b){edge[++cnt] = Edge{a, b, head[a]};head[a] = cnt;} inline void modify(int x, int k){for(;k <= n;k += lowbit(k))data[k] += x;} inline int ask(int k){int x = 0;for(;k;k -= lowbit(k))x += data[k];return x;} void dfs(int x){ b[x] = true; ans[muchang[x]] = ask(muchang[x]); modify(1, muchang[x]); for(int pos = head[x];pos;pos = edge[pos].next) { int y = edge[pos].v; if(b[y])continue; dfs(y); } modify(-1, muchang[x]); } int main() { n = read(); int tmp1,tmp2; for(int i = 1;i < n;i ++){ tmp1 = read();tmp2 = read(); insert(tmp1, tmp2); insert(tmp2, tmp1); } for(int i = 1;i <= n;i ++) muchang[read()] = i; dfs(1); for(int i = 1;i <= n;i ++) printf("%d ", ans[i]); return 0; }

     对于每只牛,我们很容易确定答案
    我们设muchang[i]表示以节点i为目的地的奶牛编号,

    那么对于奶牛k:
    muchang[k]所有祖先节点集E的muchang[e],e∈E中,满足muchang[e] < muchang[k] 的e的个数就是奶牛k的答案。
    我们要满足两个性质:
    1、得到所有祖先节点,dfs容易实现
    2、得到小于等于奶牛编号牛的个数,可以在dfs中维护树状数组
    num[i]表示奶牛i是否走过当前dfs所在节点的祖先节点,sum[i]表示前i项和,
    num[i]可在之前dfs中更新出,即每到一个节点,把num[i] += 1,每离开一个节点,把num[i] -= 1
    sum[i]就可以显然的得出答案符合性质1、2的答案

  • 相关阅读:
    jackson学习之一:基本信息 jackson学习之二:jackson-core
    FastAPI项目实战:SayHello(FastAPI + vue.js + axios + element ui 翻自Flask版
    MarkDown优雅发表
    docker使用笔记
    JVM的重要性 从上层应用程序到底层操作系统,到底有哪些东西?
    Python正则表达式re模块和os模块实现文件搜索模式匹配
    区块链学习6:图灵完备和图灵不完备
    moviepy音视频开发:使用credits1给视频加片头片尾字幕
    moviepy音视频开发:使用volumex调节音量大小及其花式用法
    moviepy音视频开发:audio_normalize调整剪辑音量大小到正常
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6849588.html
Copyright © 2011-2022 走看看