还是来致敬一下那过往吧
题目分析
先丢代码
1 #include<bits/stdc++.h>
2 const int maxn = 100035;
3 const int maxm = 200035;
4 const int maxNode = 20000035;
5
6 struct node
7 {
8 int top,son,fa,tot;
9 }a[maxn];
10 struct point
11 {
12 int u,v;
13 point(int a=0, int b=0):u(a),v(b) {}
14 };
15 struct tree
16 {
17 int ls,rs,cov,val;
18 }f[maxNode];
19 int n,m,tot;
20 long long ans,det;
21 int chain[maxn],chTot,rt[maxn];
22 int edgeTot,head[maxn],edges[maxm],nxt[maxm],dep[maxn];
23 std::vector<point> opt[maxn];
24 std::vector<int> inc[maxn],dec[maxn];
25
26 int read()
27 {
28 char ch = getchar();
29 int num = 0, fl = 1;
30 for (; !isdigit(ch); ch=getchar())
31 if (ch=='-') fl = -1;
32 for (; isdigit(ch); ch=getchar())
33 num = (num<<1)+(num<<3)+ch-48;
34 return num*fl;
35 }
36 void addedge(int u, int v)
37 {
38 edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
39 edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
40 }
41 void dfs1(int x, int fa)
42 {
43 dep[x] = dep[fa]+1, a[x].tot = 1;
44 a[x].top = a[x].son = -1, a[x].fa = fa;
45 for (int i=head[x]; i!=-1; i=nxt[i])
46 {
47 int v = edges[i];
48 if (v==fa) continue;
49 dfs1(v, x), a[x].tot += a[v].tot;
50 if (a[x].son==-1||a[a[x].son].tot < a[v].tot)
51 a[x].son = v;
52 }
53 }
54 void dfs2(int x, int top)
55 {
56 a[x].top = top, chain[x] = ++chTot;
57 if (a[x].son==-1) return;
58 dfs2(a[x].son, top);
59 for (int i=head[x]; i!=-1; i=nxt[i])
60 if (edges[i]!=a[x].fa&&edges[i]!=a[x].son)
61 dfs2(edges[i], edges[i]);
62 }
63 void splitChain(int id, int u, int v)
64 {
65 inc[u].push_back(id), inc[v].push_back(id);
66 while (a[u].top!=a[v].top)
67 {
68 if (dep[a[u].top] > dep[a[v].top]) std::swap(u, v);
69 opt[id].push_back(point(chain[a[v].top], chain[v]));
70 v = a[a[v].top].fa;
71 }
72 if (dep[u] > dep[v]) std::swap(u, v);
73 opt[id].push_back(point(chain[u], chain[v]));
74 dec[u].push_back(id), dec[a[u].fa].push_back(id);
75 }
76 void pushup(int rt, int len)
77 {
78 if (f[rt].cov) f[rt].val = len;
79 else f[rt].val = f[f[rt].ls].val+f[f[rt].rs].val;
80 }
81 void mergeSeg(int &u, int v, int l, int r)
82 {
83 if (!u||!v) u += v;
84 else{
85 int mid = (l+r)>>1;
86 f[u].cov += f[v].cov;
87 mergeSeg(f[u].ls, f[v].ls, l, mid);
88 mergeSeg(f[u].rs, f[v].rs, mid+1, r);
89 }
90 pushup(u, r-l+1);
91 }
92 void update(int &rt, int L, int R, int l, int r, int c)
93 {
94 if (!rt) rt = ++tot;
95 if (L <= l&&r <= R) f[rt].cov += c, pushup(rt, r-l+1);
96 else{
97 int mid = (l+r)>>1;
98 if (L <= mid) update(f[rt].ls, L, R, l, mid, c);
99 if (R > mid) update(f[rt].rs, L, R, mid+1, r, c);
100 }
101 pushup(rt, r-l+1);
102 }
103 void delta(int x, int fa)
104 {
105 for (int i=head[x]; i!=-1; i=nxt[i])
106 if (edges[i]!=fa) delta(edges[i], x);
107 for (int l=0; l<inc[x].size(); l++)
108 for (int i=0,mx=opt[inc[x][l]].size(); i<mx; i++)
109 update(rt[x], opt[inc[x][l]][i].u, opt[inc[x][l]][i].v, 1, n, 1);
110 for (int l=0; l<dec[x].size(); l++)
111 for (int i=0,mx=opt[dec[x][l]].size(); i<mx; i++)
112 update(rt[x], opt[dec[x][l]][i].u, opt[dec[x][l]][i].v, 1, n, -1);
113 int val = f[rt[x]].val;
114 if (val) ans += val, ++det;
115 mergeSeg(rt[fa], rt[x], 1, n);
116 }
117 int main()
118 {
119 memset(head, -1, sizeof head);
120 n = read(), m = read();
121 for (int i=1; i<n; i++)
122 addedge(read(), read());
123 dfs1(1, 0), dfs2(1, 1);
124 for (int i=1; i<=m; i++)
125 splitChain(i, read(), read());
126 delta(1, 0);
127 printf("%lld\n",(ans-det)/2);
128 return 0;
129 }
来源:https://www.cnblogs.com/antiquality/p/10846934.html