zoukankan      html  css  js  c++  java
  • [湖南集训]谈笑风生

    嘟嘟嘟


    这题刚开始犹豫了一会儿,以为“高明”的优先级大于“谈笑风生”,不过样例表明只要两点间距离不超过(x),两人就算”谈笑风生“。
    接下来看看怎么回答询问。
    首先(a)是固定的,且(a,b)都是(c)的祖先。那就得分类讨论:
    1.(b)(a)的祖先,那么(c)就是(a)的子树中的所有点,根据乘法原理,三元组个数为((size[a] - 1) * min(deep[a], x))
    2.(a)(b)的祖先。那么对于(a)子树内的每一个(b),合法的(c)都有(b)的子树大小个,所以这种情况三元组个数为(sum _ {b in a的子树,dis(a, b) leqslant a} size[b] - 1)。至于怎么求这些合法的(b),显然就是基于(dfs)序的主席树啦。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<assert.h>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 3e5 + 5;
    In ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    In void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
      freopen(".in", "r", stdin);
      freopen(".out", "w", stdout);
    #endif
    }
    
    int n, m;
    struct Edge
    {
      int nxt, to;
    }e[maxn << 1];
    int head[maxn], ecnt = -1;
    In void addEdge(int x, int y)
    {
      e[++ecnt] = (Edge){head[x], y};
      head[x] = ecnt;
    }
    
    struct Tree
    {
      int ls, rs;
      ll sum;
    }t[maxn * 40];
    int root[maxn], tcnt = 0;
    In void insert(int old, int& now, int l, int r, int val, int d)
    {
      t[now = ++tcnt] = t[old];
      t[now].sum += d;
      if(l == r) return;
      int mid = (l + r) >> 1;
      if(val <= mid) insert(t[old].ls, t[now].ls, l, mid, val, d);
      else insert(t[old].rs, t[now].rs, mid + 1, r, val, d);
    }
    In ll query(int old, int now, int l, int r, int id)
    {
      if(l == r) return t[now].sum - t[old].sum;
      int mid = (l + r) >> 1;
      if(id <= mid) return query(t[old].ls, t[now].ls, l, mid, id);
      else return t[t[now].ls].sum - t[t[old].ls].sum + query(t[old].rs, t[now].rs, mid + 1, r, id);
    }
    
    int dep[maxn], siz[maxn], dfn[maxn], pos[maxn], cnt = 0;
    In void dfs(int now, int _f)
    {
      siz[now] = 1;
      dfn[now] = ++cnt, pos[cnt] = now;
      for(int i = head[now], v; ~i; i = e[i].nxt)
        {
          if((v = e[i].to) == _f) continue;
          dep[v] = dep[now] + 1; 
          dfs(v, now);
          siz[now] += siz[v];
        }
    }
    
    int main()
    {
      MYFILE();
      Mem(head, -1);
      n = read(), m = read();
      for(int i = 1; i < n; ++i)
        {
          int x = read(), y = read();
          addEdge(x, y), addEdge(y, x);
        }
      dfs(1, 0);
      for(int i = 1; i <= cnt; ++i) insert(root[i - 1], root[i], 1, n, dep[pos[i]], siz[pos[i]] - 1);
      for(int i = 1; i <= m; ++i)
        {
          int p = read(), K = read();
          ll ans = 1LL * (siz[p] - 1) * min(dep[p], K);
          ans += query(root[dfn[p]], root[dfn[p] + siz[p] - 1], 1, n, dep[p] + K);
          write(ans), enter;
        }
      return 0;
    }
    
  • 相关阅读:
    单例模式
    Curator Zookeeper分布式锁
    LruCache算法原理及实现
    lombok 简化java代码注解
    Oracle客户端工具出现“Cannot access NLS data files or invalid environment specified”错误的解决办法
    解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。
    Redis 3.0 Cluster集群配置
    分布式锁的三种实现方式
    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
    How to Use Convolutional Neural Networks for Time Series Classification
  • 原文地址:https://www.cnblogs.com/mrclr/p/10976227.html
Copyright © 2011-2022 走看看