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
原文地址:https://www.cnblogs.com/rausen/p/4256813.html