• Codeforces Round #381 (Div. 2) D Alyona and a tree DFS+前缀和+二分查找


    D. Alyona and a tree

    链接:

    http://codeforces.com/contest/740/problem/D

    题解:

    对于在v的子树中的u,dis(u,v)其实就是dep[u]-dep[v]<=a[u],移一下就是dep[u]-a[u]<=dep[v],

    那么直接dfs下去,二分找到第一个大于等于左边的dep[v],那么相当于一个区间前缀和嘛,

    然后dfs完统计答案并且把结点pop掉。

    代码:

     1 #include <map>
     2 #include <set>
     3 #include <cmath>
     4 #include <queue>
     5 #include <stack>
     6 #include <cstdio>
     7 #include <string>
     8 #include <vector>
     9 #include <cstring>
    10 #include <sstream>
    11 #include <iostream>
    12 #include <algorithm>
    13 #include <functional>
    14 using namespace std;
    15 #define rep(i,a,n) for (int i=a;i<=n;i++)
    16 #define per(i,a,n) for (int i=n;i>=a;i--)
    17 #define pb push_back
    18 #define mp make_pair
    19 #define all(x) (x).begin(),(x).end()
    20 #define SZ(x) ((int)(x).size())
    21 typedef vector<int> VI;
    22 typedef long long ll;
    23 typedef pair<int, int> PII;
    24 const ll mod = 1e9 + 7;
    25 const int inf = 0x3f3f3f3f;
    26 const double eps = 1e-7;
    27 // head
    28 
    29 const int maxn = 2e5 + 7;
    30 vector<pair<int, ll> > e[maxn];
    31 vector<pair<ll, int> > path;
    32 ll a[maxn], dep[maxn], ans[maxn];
    33 
    34 void dfs(int u){
    35     ans[u]++;
    36     int p = lower_bound(path.begin(), path.end(), make_pair(dep[u] - a[u], -1)) - path.begin();
    37     p--;
    38     if (p >= 0) ans[path[p].second]--;
    39      path.pb(mp(dep[u], u));
    40     for (int i = 0; i < e[u].size(); i++){
    41         int v = e[u][i].first;
    42         ll w = e[u][i].second;
    43         dep[v] = dep[u] + w;
    44         dfs(v);
    45         ans[u] += ans[v];
    46     }
    47     path.pop_back();
    48 }
    49 
    50 int main(){
    51     ios::sync_with_stdio(false);
    52     int n;
    53     cin >> n;
    54     rep(i, 1, n) cin >> a[i];
    55     rep(i, 2, n) {
    56         int p; ll w;
    57         cin >> p >> w;
    58         e[p].pb(mp(i, w));
    59     }
    60     dfs(1);
    61     rep(i, 1, n) cout << ans[i] - 1 << " ";
    62     return 0;
    63 }

    树状数组

      1 #include <map>
      2 #include <set>
      3 #include <cmath>
      4 #include <queue>
      5 #include <stack>
      6 #include <cstdio>
      7 #include <string>
      8 #include <vector>
      9 #include <cstring>
     10 #include <sstream>
     11 #include <iostream>
     12 #include <algorithm>
     13 #include <functional>
     14 using namespace std;
     15 #define rep(i,a,n) for (int i=a;i<=n;i++)
     16 #define per(i,a,n) for (int i=n;i>=a;i--)
     17 #define pb push_back
     18 #define mp make_pair
     19 #define all(x) (x).begin(),(x).end()
     20 #define SZ(x) ((int)(x).size())
     21 typedef vector<int> VI;
     22 typedef long long ll;
     23 typedef pair<int, int> PII;
     24 const ll mod = 1e9 + 7;
     25 const int inf = 0x3f3f3f3f;
     26 const double eps = 1e-7;
     27 // head
     28 
     29 #define LL long long  
     30 const int maxn = 2e5 + 5;
     31 int a[maxn], in[maxn], out[maxn], c[maxn], ans[maxn];  //a-每个点的值,in-dfs该点的顺序,out-该点的子树最远的叶子  
     32 LL dis[maxn]; //每个点到根的距离  
     33 vector<int> g[maxn], w[maxn];  //g-建树,w-每条边的值  
     34 int n, ord = 0;
     35 
     36 struct node {
     37     int tp, id;
     38     LL v;
     39     node(){}
     40     node(int a, int b, LL c) {
     41         tp = a, id = b, v = c;
     42     }
     43 } b[maxn * 2];
     44 
     45 bool cmp(node a, node b) {
     46     if (a.v == b.v) return a.tp < b.tp;
     47     return a.v < b.v;
     48 }
     49 
     50 void dfs(int x, LL d) {  //dfs in-标记每个点遍历的顺序,out-该点的子树最远的叶子,dis-该点到根节点的距离  
     51     dis[x] = d;
     52     in[x] = ++ord;
     53     for (int i = 0; i < g[x].size(); i++) {
     54         dfs(g[x][i], d + w[x][i]);
     55     }
     56     out[x] = ord;
     57 }
     58 
     59 void add(int x) {
     60     while (x <= n) {
     61         c[x]++;
     62         x += x&-x; //lowbit直接写在函数里面,看起来简洁些  
     63     }
     64 }
     65 
     66 int query(int x) {
     67     int ans = 0;
     68     while (x) {
     69         ans += c[x];
     70         x -= x&-x;
     71     }
     72     return ans;
     73 }
     74 
     75 int main() {
     76     scanf("%d", &n);
     77     for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
     78     for (int i = 2; i <= n; i++) {
     79         int u, v;
     80         scanf("%d%d", &u, &v);
     81         g[u].pb(i);
     82         w[u].pb(v);
     83     }
     84     dfs(1, 0);
     85     int cnt = 0;
     86     for (int i = 1; i <= n; i++) {
     87         b[++cnt] = node(1, i, dis[i] - a[i]);
     88         b[++cnt] = node(2, i, dis[i]);
     89     }    
     90     sort(b + 1, b + 1 + cnt, cmp);
     91     for (int i = 1; i <= cnt; i++) printf("%d  %d  %I64d
    ", b[i].tp, b[i].id, b[i].v);
     92     memset(c, 0, sizeof(c));
     93     for (int i = 1; i <= cnt; i++) {
     94         if (b[i].tp == 1) add(in[b[i].id]);
     95         else {
     96             ans[b[i].id] = query(out[b[i].id]) - query(in[b[i].id] - 1);
     97         }
     98     }
     99     for (int i = 1; i <= n; i++)
    100         printf("%d ", ans[i] - 1);  //得到的答案包含它本身,所以要减一  
    101     puts("");
    102 }
  • 相关阅读:
    heml学习笔记
    离线安装
    linux 监测网络流量的工具 ifstat
    Python的 “内存管理机制”,转载,内存泄漏时感觉应该看下
    http 请求
    Java之调用Python代码 转载:https://mp.weixin.qq.com/s/cr8dXzwsQhtei9TfXwcMcA
    python 加密 so 转载:https://mp.weixin.qq.com/s/xmr3fs72XeJn-sMIoGftNA
    migrate
    查看 GPU 基本信息 nvidia-smi 命令
    MVC 基于 AuthorizeAttribute 实现的登陆权限控制
  • 原文地址:https://www.cnblogs.com/baocong/p/6527426.html
Copyright © 2020-2023  润新知