Farmer John is planning to build NN (1≤N≤1051≤N≤105) farms that will be connected by N−1N−1 roads, forming a tree (i.e., all farms are reachable from each-other, and there are no cycles). Each farm contains a cow with an integer type TiTi between 11 and NN inclusive.
Farmer John's MM friends (1≤M≤1051≤M≤105) often come to visit him. During a visit with friend ii, Farmer John will walk with his friend along the unique path of roads from farm AiAi to farm BiBi (it may be the case that Ai=BiAi=Bi). Additionally, they can try some milk from any cow along the path they walk. Since most of Farmer John's friends are also farmers, they have very strong preferences regarding milk. Each of his friends will only drink milk from a certain type of cow. Any of Farmer John's friends will only be happy if they can drink their preferred type of milk during their visit.
Please determine whether each friend will be happy after visiting.
The first line contains two integer NN and MM.The second line contains NN space-separated integers T1,T2,…,TN.T1,T2,…,TN. The type of the cow in the ii-th farm is denoted by Ti.Ti.
The next N−1N−1 lines each contain two distinct integers XX and YY (1≤X,Y≤N1≤X,Y≤N), indicating that there is an edge between farms XX and YY.
The next MM lines contain integers AiAi, BiBi, and CiCi. AiAi and BiBi represent the endpoints of the path walked during friend ii's visit, while CiCi (1≤Ci≤N1≤Ci≤N) indicates the type of cow whose milk the friend enjoys drinking.
Print a binary string of length M.M. The iith character of the string should be '1' if the iith friend will be happy, or '0' otherwise.
5 5 1 1 2 1 2 1 2 2 3 2 4 1 5 1 4 1 1 4 2 1 3 2 1 3 1 5 5 1
10110
In this example, the path from 1 and 4 involves farms 1, 2, and 4. All of these contain cows of type 1, so the first friend will be satisfied while the second one will not.
6 4 1 2 3 3 3 3 1 2 2 3 3 4 2 5 5 6 4 6 1 4 6 2 4 6 3 4 6 4
0110
Problem credits: Spencer Compton
<h3> USACO 2019 December Contest, Gold Problem 2. Milk Visits 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Benjamin Qi)
We can answer the queries offline (meaning that we process them in an order that is convenient for us, not that which is given by the input). Like the silver version, run a DFS from farm 11. Suppose that we're currently processing the farm x.x. Store a stack ordord containing all the nodes on the path from 11 to x,x, and also a stack stor[t]stor[t] for each type tt containing the pairs (y,depth[y])(y,depth[y]) for all farms yy with type tt on the path from 11 to x.x.
Suppose that we want to update the answer for a query ii having an endpoint Ai=xAi=x (the reasoning for Bi=xBi=x is similar). We need to check whether the last farm yy in the stack corresponding to CiCi actually lies on the path from AiAi to BiBi. Let LL be the least common ancestor of AiAi and Bi.Bi. First, we can check whether yy is an ancestor of BiBi in O(1)O(1) using the preorder and postorder traversals of the tree. If not, then yy lies on the path between AiAi and Li,Li, so the answer to this query must be 1. If yes, then it's still possible for yy to lie on the path from AiAi to BiBi if y=Liy=Li.
One option is to actually find LiLi and compare it to y,y, but this is unnecessary. Instead, if y≠Aiy≠Ai then consider the farm Y=ord[depth[y]+1].Y=ord[depth[y]+1]. If YY is an ancestor of Bi,Bi, then yy is clearly not the LCA. Otherwise, AiAi and BiBi lie in different child subtrees of y,y, implying that yy is the LCA.
Thus, this problem is solvable in O(N+M)O(N+M) time.
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pi; typedef vector<int> vi; typedef vector<pi> vpi; #define FOR(i, a, b) for (int i = (a); i < (b); i++) #define F0R(i, a) for (int i = 0; i < (a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define trav(a, x) for (auto& a : x) #define mp make_pair #define pb push_back #define f first #define s second #define sz(x) (int)x.size() #define all(x) begin(x), end(x) #define rsz resize const int MX = 100005; void setIO(string name) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } int N,M,T[MX],C[MX]; bool ok[MX]; vi adj[MX]; array<int,2> dat[MX]; vi todo[MX]; pi range[MX]; int co = 0; void dfs(int x, int y) { range[x].f = co++; trav(t,adj[x]) if (t != y) dfs(t,x); range[x].s = co-1; } vpi stor[MX]; vi ord; bool anc(int a, int b) { return range[a].f <= range[b].f && range[b].s <= range[a].s; } void dfs2(int x, int y) { stor[T[x]].pb({x,sz(ord)}); ord.pb(x); trav(t,todo[x]) if (sz(stor[C[t]])) { pi y = stor[C[t]].back(); if (y.f == x) ok[t] = 1; else { int Y = ord[y.s+1]; // x is one of endpoints for query t assert(dat[t][0] == x || dat[t][1] == x); if (!anc(Y,dat[t][0]+dat[t][1]-x)) ok[t] = 1; } } trav(t,adj[x]) if (t != y) dfs2(t,x); stor[T[x]].pop_back(); ord.pop_back(); } int main() { setIO("milkvisits"); cin >> N >> M; FOR(i,1,N+1) cin >> T[i]; F0R(i,N-1) { int A,B; cin >> A >> B; adj[A].pb(B), adj[B].pb(A); } dfs(1,0); F0R(i,M) { cin >> dat[i][0] >> dat[i][1] >> C[i]; F0R(j,2) todo[dat[i][j]].pb(i); } dfs2(1,0); F0R(i,M) { if (ok[i]) cout << 1; else cout << 0; } cout << "\n"; }
Bonus: solve the problem online in O((N+M)logN).
[/hide]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1