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]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1