zoukankan      html  css  js  c++  java
  • BZOJ3772 精神污染

    写这道题写的真是被精神污染了。。。主席树什么的全都不会了唔

    还是Orz PoPoQQQ吧,原来打算写题解的,写了半个小时发现语文不好2333

      1 /**************************************************************
      2     Problem: 3772
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:3960 ms
      7     Memory:62540 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12 #include <vector>
     13  
     14 using namespace std;
     15 typedef long long ll;
     16 const int N = 100010;
     17 const int M = N;
     18 const int cnt_segment = 3804000;
     19  
     20 struct edge {
     21   int next, to;
     22   edge() {}
     23   edge(int _n, int _t) : next(_n), to(_t) {} 
     24 } e[N << 1];
     25  
     26 struct Query {
     27   int x, y;
     28   Query() {}
     29   Query(int _x, int _y) : x(_x), y(_y) {}
     30  
     31   inline bool operator < (const Query &a) const {
     32     return x == a.x ? y < a.y : x < a.x;
     33   }
     34   inline bool operator == (const Query &a) const {
     35     return x == a.x && y == a.y;
     36   }
     37 } Q[M];
     38  
     39 struct seg_node {
     40   seg_node *ls, *rs;
     41   int val;
     42 } *seg[N], mempool[cnt_segment], *cnt_seg = mempool;
     43  
     44 struct tree_node {
     45   int fa[18], dep, st, ed;
     46 } tr[N];
     47  
     48 int n, m;
     49 int first[N], tot;
     50 int cnt_dfs;
     51 ll ans1, ans2, g;
     52 vector <int> a[N];
     53  
     54 inline int read() {
     55   int x = 0;
     56   char ch = getchar();
     57   while (ch < '0' || '9' < ch)
     58     ch = getchar();
     59   while ('0' <= ch && ch <= '9')
     60     (x *= 10) += ch - '0', ch = getchar();
     61   return x;
     62 }
     63  
     64 inline ll gcd(ll a, ll b) {
     65   return a ? gcd(b % a, a) : b;
     66 }
     67  
     68 inline void Add_edges(int x, int y) {
     69   e[++tot] = edge(first[x], y), first[x] = tot;
     70   e[++tot] = edge(first[y], x), first[y] = tot;
     71 }
     72  
     73 #define mid (l + r >> 1)
     74 void seg_modify(seg_node *&p, int l, int r, int pos, int v) {
     75   *(++cnt_seg) = *p, p = cnt_seg, p -> val += v;
     76   if (l == r) return;
     77   if (pos <= mid) seg_modify(p -> ls, l, mid, pos, v);
     78   else seg_modify(p -> rs, mid + 1, r, pos, v);
     79 }
     80  
     81 int get_ans(seg_node *p1, seg_node *p2, seg_node *p3, seg_node *p4, int l, int r, int x, int y) {
     82   if (l == x && y == r)
     83     return p1 -> val + p2 -> val - p3 -> val - p4 -> val;
     84   if (y <= mid)
     85     return get_ans(p1 -> ls, p2 -> ls, p3 -> ls, p4 -> ls, l, mid, x, y);
     86   if (mid < x)
     87     return get_ans(p1 -> rs, p2 -> rs, p3 -> rs, p4 -> rs, mid + 1, r, x, y);
     88   return get_ans(p1 -> ls, p2 -> ls, p3 -> ls, p4 -> ls, l, mid, x, mid) +
     89     get_ans(p1 -> rs, p2 -> rs, p3 -> rs, p4 -> rs, mid + 1, r, mid + 1, y);
     90 }
     91 #undef mid
     92  
     93 #define y e[x].to
     94 void dfs1(int p) {
     95   int x;
     96   tr[p].st = ++cnt_dfs;
     97   for (x = 1; x <= 17; ++x)
     98     tr[p].fa[x] = tr[tr[p].fa[x - 1]].fa[x - 1];
     99   for (x = first[p]; x; x = e[x].next)
    100     if (y != tr[p].fa[0]) {
    101       tr[y].fa[0] = p, tr[y].dep = tr[p].dep + 1;
    102       dfs1(y);
    103     }
    104   tr[p].ed = ++cnt_dfs;
    105 }
    106  
    107 void dfs2(int p) {
    108   int x;
    109   vector <int> :: iterator IT;
    110   seg[p] = seg[tr[p].fa[0]];
    111   for (IT = a[p].begin(); IT != a[p].end(); ++IT) {
    112     seg_modify(seg[p], 1, n << 1, tr[*IT].st, 1);
    113     seg_modify(seg[p], 1, n << 1, tr[*IT].ed, -1);
    114   }
    115   for (x = first[p]; x; x = e[x].next)
    116     if (y != tr[p].fa[0]) dfs2(y);
    117 }
    118 #undef y
    119  
    120 inline int get_lca(int x, int y) {
    121   int i;
    122   if (tr[x].dep < tr[y].dep) swap(x, y);
    123   for (i = 17; ~i; --i)
    124     if (tr[tr[x].fa[i]].dep >= tr[y].dep)
    125       x = tr[x].fa[i];
    126   for (i = 17; ~i; --i)
    127     if (tr[x].fa[i] != tr[y].fa[i])
    128       x = tr[x].fa[i], y = tr[y].fa[i];
    129   return x == y ? x : tr[x].fa[0];
    130 }
    131  
    132 int main() {
    133   int i, j, x, y, lca;
    134   n = read(), m = read();
    135   for (i = 1; i < n; ++i) Add_edges(read(), read());
    136   for (i = 1; i <= m; ++i) {
    137     x = read(), y = read();
    138     a[x].push_back(y);
    139     Q[i] = Query(x, y);
    140   }
    141   seg[0] = ++cnt_seg, seg[0] -> ls = seg[0] -> rs = seg[0];
    142   tr[1].dep = 1;
    143   dfs1(1);
    144   dfs2(1);
    145   for (i = 1; i <= m; ++i) {
    146     x = Q[i].x, y = Q[i].y, lca = get_lca(x, y);
    147     ans1 += get_ans(seg[x], seg[y], seg[lca], seg[tr[lca].fa[0]], 1, n << 1, tr[lca].st, tr[x].st);
    148     ans1 += get_ans(seg[x], seg[y], seg[lca], seg[tr[lca].fa[0]], 1, n << 1, tr[lca].st, tr[y].st);
    149     ans1 -= get_ans(seg[x], seg[y], seg[lca], seg[tr[lca].fa[0]], 1, n << 1, tr[lca].st, tr[lca].st);
    150     --ans1;
    151   }
    152   sort(Q + 1, Q + m + 1);
    153   for (i = 1; i <= m; i = j) {
    154     for (j = i + 1; j <= m && Q[i] == Q[j]; ++j);
    155     ans1 -= (ll) (j - i) * (j - i - 1) >> 1;
    156     }
    157   ans2 = (ll) m * (m - 1) >> 1;
    158   g = gcd(ans1, ans2);
    159   printf("%lld/%lld
    ", ans1 / g, ans2 / g);
    160   return 0;
    161 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    GNU安装
    camera链接
    右键terminal
    Angular cli 常见问题
    Angular路由复用策略RouteReuseStrategy
    angular5 websocket 服务
    promise 极简版封装
    js a 标签 通过download 实现下载功能
    angular6 升级到 angular7+ 最新Ng-zorro
    最新IDEA永久激活
  • 原文地址:https://www.cnblogs.com/rausen/p/4256813.html
Copyright © 2011-2022 走看看