Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define ld double
- #define mod 1000000007
- int col[100010], cnt[100010];
- ll seq[100010];
- int res[100010];
- ll h[100010], h2[100010];
- vector <int> g[100010];
- int sz[100010];
- ll val=0, val2=0;
- bool big[100010];
- void calcSz(int src, int par)
- {
- sz[src]=1;
- for(auto x: g[src])
- {
- if(x==par)
- continue;
- calcSz(x, src);
- sz[src]+=sz[x];
- }
- return;
- }
- void add(int src, int par, int x)
- {
- cnt[col[src]]+=x;
- // if(x==1) cout<<src<<endl;
- if(x==1 && cnt[col[src]]==1)
- val+=h[col[src]], val%=mod, val2+=h2[col[src]], val2%=mod;
- if(x==-1 && cnt[col[src]]==0)
- val+=mod-h[col[src]], val%=mod, val2+=mod-h2[col[src]], val2%=mod;
- for(auto y: g[src])
- {
- if(y==par || big[y])
- continue;
- add(y, src, x);
- }
- }
- void dfs(int v, int p, bool keep)
- {
- int mx = -1, bigChild = -1;
- for(auto u : g[v])
- if(u != p && sz[u] > mx)
- mx = sz[u], bigChild = u;
- for(auto u : g[v])
- if(u != p && u != bigChild)
- dfs(u, v, 0);
- if(bigChild != -1)
- dfs(bigChild, v, 1), big[bigChild] = 1;
- add(v, p, 1);
- // if(v==4) cout<<cnt[3]<<endl;
- seq[v]=val|(val2<<31);
- if(bigChild != -1)
- big[bigChild] = 0;
- if(keep == 0)
- add(v, p, -1);
- }
- void add2(int src, int par, int x)
- {
- cnt[col[src]]+=x;
- if(x==1 && cnt[col[src]]==1)
- val+=1;
- if(x==-1 && cnt[col[src]]==0)
- val-=1;
- for(auto y: g[src])
- {
- if(y==par || big[y])
- continue;
- add2(y, src, x);
- }
- }
- void dfs2(int v, int p, bool keep)
- {
- int mx = -1, bigChild = -1;
- for(auto u : g[v])
- if(u != p && sz[u] > mx)
- mx = sz[u], bigChild = u;
- for(auto u : g[v])
- if(u != p && u != bigChild)
- dfs2(u, v, 0);
- if(bigChild != -1)
- dfs2(bigChild, v, 1), big[bigChild] = 1;
- add2(v, p, 1);
- res[v]=val;
- if(bigChild != -1)
- big[bigChild] = 0;
- if(keep == 0)
- add2(v, p, -1);
- }
- map<ll, int> mp1;
- ll fastPow(ll x, ll y)
- {
- if(y==0)
- return 1;
- ll ret=fastPow(x, y/2);
- ret=ret*ret;
- ret%=mod;
- if(y%2==1)
- ret*=x, ret%=mod;
- return ret;
- }
- int main()
- {
- int i, j, n, m, t;
- for(i=1; i<=100001; i++)
- {
- h[i]=fastPow(i, 10000000799LL);
- h2[i]=fastPow(i, 9772133383LL);
- // if(mp1[h[i]]) cout<<i<<endl;
- // mp1[h[i]]=1;
- }
- scanf("%d", &t);
- while(t--)
- {
- scanf("%d", &n);
- int id=2;
- mp1.clear();
- for(i=0; i<=n; i++)
- {
- g[i].clear();
- sz[i]=0;
- }
- // cout<<"*";
- for(i=1; i<=n; i++)
- {
- int x;
- scanf("%d", &x);
- if(mp1[x] == 0)
- mp1[x]=id++;
- col[i]=mp1[x];
- // cout<<col[i]<<" ";
- }
- // cout<<endl;
- int root=0;
- for(i=1; i<=n; i++)
- {
- int u;
- scanf("%d", &u);
- if(u==-1)
- root=i;
- else
- g[u].push_back(i);
- }
- for(i=0; i<=n+1; i++)
- {
- cnt[i]=0;
- big[i]=0;
- }
- val=0;
- calcSz(root, -1);
- dfs(root, -1, 0);
- mp1.clear();
- id=1;
- for(i=1; i<=n; i++)
- {
- // cout<<seq[i]<<" ";
- if(mp1[seq[i]]==0)
- mp1[seq[i]]=id++;
- col[i]=mp1[seq[i]];
- }
- // cout<<endl;
- for(i=0; i<=n+1; i++)
- {
- cnt[i]=0;
- big[i]=0;
- }
- val=0;
- dfs2(root, -1, 0);
- for(i=1; i<=n; i++)
- printf("%d ", res[i]);
- printf("\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment