Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- using namespace std;
- using namespace __gnu_pbds;
- #define debug(x) cerr << '[' << (#x) << "] = " << x << '\n';
- template<class T> using ordered_set = tree<T, null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update> ;
- const int maxn = 1e5 + 5;
- vector<int>g[maxn];
- void PlayGround() {
- int n; cin >> n;
- int p[n+1], v[n+1];
- for(int i=1; i<=n; ++i) cin >> v[i];
- for(int i=2; i<=n; ++i) {
- int pa; cin >> pa;
- g[pa].push_back(i);
- }
- int timer = 1;
- int st[n+1], en[n+1];
- function<void(int,int)> DFS = [&] (int node, int parent) {
- st[node] = timer++;
- for(auto it : g[node]) DFS(it, node);
- en[node] = timer - 1;
- };
- DFS(1, 1);
- for(int node=1; node <= n; ++node) p[st[node]] = v[node];
- vector<vector<int>>segmentTree(n<<2, vector<int>());
- auto merge = [=] (vector<int>a, vector<int>b) {
- int p0 = 0, p1 = 0;
- int n = a.size(), m = b.size();
- vector<int>ret;
- while(p0<n || p1<m) {
- if(p0==n) {
- ret.push_back(b[p1++]);
- } else if(p1==m) {
- ret.push_back(a[p0++]);
- } else {
- if(a[p0]<=b[p1]) ret.push_back(a[p0++]);
- else ret.push_back(b[p1++]);
- }
- }
- assert(is_sorted(ret.begin(), ret.end()));
- return ret;
- };
- function<void(int,int,int)> Build = [&] (int l, int r, int node) {
- if(l==r) {
- segmentTree[node].push_back(p[l]);
- return;
- }
- int mid = (l+r)>>1;
- Build(l, mid, node+node);
- Build(mid+1, r, node+node+1);
- segmentTree[node] = merge(segmentTree[node+node], segmentTree[node+node+1]);
- };
- Build(1, n, 1);
- function<int(int,int,int,int,int,int)> Query = [&] (int l, int r, int L, int R, int val, int node) {
- if(l>=L && r<=R) {
- return (int)(segmentTree[node].end() - upper_bound(segmentTree[node].begin(), segmentTree[node].end(), val));
- }
- if(l>R || r<L) return 0;
- int mid = (l+r)>>1;
- return Query(l, mid, L, R, val, node+node) + Query(mid+1, r, L, R, val, node+node+1);
- };
- for(int node=1; node<=n; ++node)
- cout << Query(1, n, st[node], en[node], p[st[node]], 1) << '\n';
- #ifndef ONLINE_JUDGE
- cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
- #endif
- }
- int main() {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- #ifndef ONLINE_JUDGE
- //freopen("input.txt", "r", stdin);
- freopen("promote.in", "r", stdin);
- freopen("promote.out", "w", stdout);
- #endif
- PlayGround();
- return 0;
- }
Add Comment
Please, Sign In to add comment