2022春每日一題:Day 38
阿新 • • 發佈:2022-03-16
題目[USACO17JAN]Promotion Counting P
從根節點dfs一遍,樹狀陣列維護進入和出去時這個節點的貢獻,一減就是答案
程式碼:
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #define lowbit(x) x&-x const int N=1e5+5; using namespace std; struct pos { int v,id; pos(int vv,int ii) { v=vv;id=ii; } pos(){ } friend bool operator < (pos a,pos b) { return a.v<b.v; } }nums[N]; int n,a[N],fs[N],fe[N],tot; vector <int> g[N]; namespace fenwick { struct fw { int c; }e[N]; void modify(int x,int v) { for(int i=x;i<=n;i+=lowbit(i)) e[i].c+=v; } int query(int x) { int ret=0; for(int i=x;i;i-=lowbit(i)) ret+=e[i].c; return ret; } } using namespace fenwick; void dfs(int u,int fa) { ++tot; modify(a[u],1); fs[u]=tot-query(a[u]); for(int i=0;i<g[u].size();i++) { int k=g[u][i]; if(k==fa) continue; dfs(k,u); } fe[u]=tot-query(a[u]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int v; scanf("%d",&v); nums[i]=pos(v,i); } for(int i=2;i<=n;i++) { int v; scanf("%d",&v); g[v].push_back(i); g[i].push_back(v); } sort(nums+1,nums+1+n); int last=-1,now=1; for(int i=1;i<=n;i++) { if(last!=nums[i].v) last=nums[i].v,now=i; a[nums[i].id]=now; } dfs(1,0); for(int i=1;i<=n;i++) printf("%d\n",fe[i]-fs[i]); return 0; }