Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define vi vector<int>
- using namespace std;
- const int ILE = 100005;
- const int pot = (1<<19);
- int jump[21][ILE];
- int nopath[ILE];
- int deep[ILE];
- int dr[pot*2];
- vi paths[ILE];
- int path[ILE];
- int start[ILE];
- int card[ILE];
- int id[ILE];
- vi g[ILE];
- int p_num = 1;
- int id_num = 0;
- bool light(int a, int b)
- {
- return card[b]*2 >= card[a];
- }
- void dfs1(int x, int pop)
- {
- deep[x] = deep[pop]+1;
- jump[0][x] = pop;
- card[x] = 1;
- for(auto it : g[x])
- {
- if(it != pop)
- {
- dfs1(it, x);
- card[x] += card[it];
- }
- }
- }
- void dfs2(int x, int pop)
- {
- for(auto it : g[x])
- {
- if(it != pop)
- {
- if(light(x, it))
- {
- if(path[x])
- {
- path[it] = path[x];
- paths[path[x]].push_back(it);
- }
- else
- {
- path[it] = p_num++;
- paths[path[it]].push_back(it);
- start[path[it]] = it;
- }
- }
- dfs2(it, x);
- }
- }
- }
- int lca(int a, int b)
- {
- if(deep[a] < deep[b])swap(a, b);
- for(int i=20; i>=0; i--)
- {
- if(deep[jump[i][a]] >= deep[b])a = jump[i][a];
- }
- if(a == b)return b;
- for(int i=20; i>=0; i--)
- {
- if(jump[i][a] != jump[i][b])
- {
- a = jump[i][a];
- b = jump[i][b];
- }
- }
- return jump[0][a];
- }
- void add(int a, int b)
- {
- if(deep[a] < deep[b])cout<<"WRONG";
- for(a = id[a] + pot, b += id[b] + pot+1; a<b; a/=2, b/=2)
- {
- if(a&1)dr[a++]++;
- if(b&1)dr[--b]++;
- }
- }
- void odd(int a, int b)
- {
- if(deep[a] < deep[b])cout<<"WRONG";
- for(a = id[a] + pot, b = id[b] + pot+1; a<b; a/=2, b/=2)
- {
- if(a&1)dr[a++]--;
- if(b&1)dr[--b]--;
- }
- }
- int ask(int a, int b, int ans = 0)
- {
- if(deep[a] < deep[b])
- swap(a, b);
- if(!path[a])
- return nopath[a];
- else
- {
- a = id[a] + pot;
- while(a > 0)
- ans += dr[a], a/=2;
- return ans;
- }
- }
- void hld(int a, int b)
- {
- int LCA = lca(a, b);
- while(a != LCA)
- {
- if(!path[a])
- {
- nopath[a]++;
- a = jump[0][a];
- }
- else
- {
- add(start[path[a]], a);
- if(path[a] != path[LCA])
- {
- a = jump[0][start[path[a]]];
- }
- else
- {
- odd(start[path[a]], LCA);
- a = LCA;
- }
- }
- }
- while(b != LCA)
- {
- if(!path[b])
- {
- nopath[b]++;
- b = jump[0][b];
- }
- else
- {
- add(start[path[b]], b);
- if(path[b] != path[LCA])
- {
- b = jump[0][start[path[b]]];
- }
- else
- {
- odd(start[path[b]], LCA);
- b = LCA;
- }
- }
- }
- }
- int main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- int n, m, a, b, q;
- cin>>n>>q;
- for(int i=0; i<n-1; i++)
- {
- cin>>a>>b;
- g[a].push_back(b);
- g[b].push_back(a);
- }
- dfs1(1, 0);
- for(int i=1; i<=20; i++)
- {
- for(int j=1; j<=n; j++)
- {
- jump[i][j] = jump[i-1][jump[i-1][j]];
- }
- }
- dfs2(1, 0);
- for(int i=1; i<p_num; i++)
- for(auto it : paths[i])
- {
- id[it] = id_num++;
- }
- char v;
- for(int i=0; i<q; i++)
- {
- cin>>v>>a>>b;
- if(v == 'P')
- hld(a, b);
- else
- cout<<ask(a, b)<<"\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement