Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define fixed(n) fixed << setprecision(n)
- #define ceil(n, m) (((n) + (m) - 1) / (m))
- #define add_mod(a, b, m) (((a % m) + (b % m)) % m)
- #define sub_mod(a, b, m) (((a % m) - (b % m) + m) % m)
- #define mul_mod(a, b, m) (((a % m) * (b % m)) % m)
- #define all(vec) vec.begin(), vec.end()
- #define rall(vec) vec.rbegin(), vec.rend()
- #define sz(x) int(x.size())
- #define debug(x) cout << #x << ": " << (x) << "\n";
- #define fi first
- #define se second
- #define ll long long
- #define ull unsigned long long
- #define EPS 1e-9
- constexpr int INF = 1 << 30, Mod = 1e9 + 7;
- constexpr ll LINF = 1LL << 62;
- #define PI acos(-1)
- template < typename T = int > using Pair = pair < T, T >;
- vector < string > RET = {"NO", "YES"};
- template < typename T = int > istream& operator >> (istream &in, vector < T > &v) {
- for (auto &x : v) in >> x;
- return in;
- }
- template < typename T = int > ostream& operator << (ostream &out, const vector < T > &v) {
- for (const T &x : v) out << x << ' ';
- return out;
- }
- template < typename T = int > struct LCA {
- struct Edge {
- ll v, w;
- Edge(ll V = 0, ll W = 0) : v(V), w(W) {}
- bool operator < (const Edge &rhs) const {
- return w < rhs.w;
- }
- };
- int N, LOG;
- vector < vector < T > > anc;
- vector < vector < T > > adj;
- vector < T > dep, val;
- LCA(int n, const vector < vector < T > >& G, const vector < T >& W){
- N = n + 10, LOG = 0;
- while((1 << LOG) <= n) LOG++;
- dep = vector < T > (N);
- anc = vector < vector < T > > (N, vector < T > (LOG));
- val = W, adj = G;
- }
- T operation(T a, T b){
- return (a & b);
- }
- void dfs(int u, int p = 0){
- for(auto& v : adj[u]){
- if(v == p) continue;
- dep[v] = dep[u] + 1, anc[v][0] = u;
- for(int bit = 1; bit < LOG; bit++)
- anc[v][bit] = anc[anc[v][bit - 1]][bit - 1];
- dfs(v, u);
- }
- }
- int kth_ancestor(int u, int k){
- if(dep[u] < k)
- return -1;
- for(int bit = LOG - 1; bit >= 0; bit--)
- if(k & (1 << bit))
- u = anc[u][bit];
- return u;
- }
- int get_lca(int u, int v){
- if(dep[u] < dep[v])
- swap(u, v);
- u = kth_ancestor(u, dep[u] - dep[v]);
- if(u == v)
- return u;
- for(int bit = LOG - 1; bit >= 0; bit--)
- if(anc[u][bit] != anc[v][bit])
- u = anc[u][bit], v = anc[v][bit];
- return anc[u][0];
- }
- T get_cost(int u, int dist){
- if(dep[u] < dist) return -1;
- return val[kth_ancestor(u, dist)];
- }
- T query(int u, int k){
- int l = 1, r = dep[u], ans = -1;
- while(l <= r){
- int m = l + (r - l) / 2;
- (get_cost(u, m) <= k ? r = m - 1, ans = m : l = m + 1);
- }
- if(ans == -1)
- return -1;
- return kth_ancestor(u, ans);
- }
- void build_cost(int root = 1, int p = 0){
- for(auto& v : adj[root]){
- if(v == p) continue;
- build_cost(v, root);
- val[root] = operation(val[root], val[v]);
- }
- }
- void build(int root = 1){
- build_cost(root);
- dfs(root);
- }
- };
- void Solve(){
- int n, q;
- cin >> n >> q;
- vector < vector < ll > > adj(n + 5);
- vector < ll > values(n + 5), par(n + 5);
- for(int i = 2; i <= n; i++)
- cin >> par[i];
- for(int i = 1; i <= n; i++)
- cin >> values[i];
- for(int i = 2; i <= n; i++)
- adj[par[i]].push_back(i);
- LCA < ll > lca(n, adj, values);
- lca.build();
- while(q--){
- int u, k;
- cin >> u >> k;
- cout << lca.query(u, k) << '\n';
- }
- }
- int main(){
- ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
- int test_cases = 1;
- // cin >> test_cases;
- for(int tc = 1; tc <= test_cases; tc++){
- // cout << "Case #" << tc << ": ";
- Solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement