记录编号 89071 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2004] 树的果实 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 1.485 s
提交时间 2014-02-28 14:48:20 内存使用 5.28 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<vector>
  5. #include<algorithm>
  6. #include<iomanip>
  7. #include<map>
  8. using namespace std;
  9. const int SIZEN=100100;
  10. int N;
  11. int father[SIZEN]={0};
  12. vector<int> c[SIZEN];//儿子
  13. int delic[SIZEN]={0};//美味值
  14. int numpst[SIZEN]={0};//子树上节点个数
  15. int A[SIZEN]={0},B[SIZEN]={0},C[SIZEN]={0};//分别对应三个答案
  16. //即:上面部分(子树),下面部分(除了子树),树根到该点路径中更美味的果子个数
  17. map<int,int> dlcmp;//离散化后的美味值
  18. int numval;//不同美味值的个数
  19. int dfn[SIZEN]={0};//时间戳
  20. class TARRAY{//树状数组
  21. public:
  22. int n;//范围1~n
  23. int s[SIZEN];
  24. void clear(int x){memset(s,0,sizeof(s)),n=x;}
  25. int lowbit(int x){return x&(-x);}
  26. int prefsum(int x){//前缀和
  27. int ans=0;
  28. for(int i=x;i>0;i-=lowbit(i)) ans+=s[i];
  29. return ans;
  30. }
  31. int segsum(int x,int y){//区间[x,y]的和
  32. if(x>y) return 0;
  33. return prefsum(y)-prefsum(x-1);
  34. }
  35. void change(int x,int t){//第x个元素+t
  36. for(int i=x;i<=n;i+=lowbit(i)) s[i]+=t;
  37. }
  38. };
  39. TARRAY tree;//树状数组
  40. pair<int,int> sorted[SIZEN];//first是美味值,second是位置
  41. void work(void){
  42. tree.clear(N);
  43. for(int i=1;i<=N;i++) sorted[i]=make_pair(delic[i],i);
  44. sort(sorted+1,sorted+1+N);
  45. for(int i=N;i>=1;){
  46. int j;
  47. for(j=i;sorted[j].first==sorted[i].first;j--){
  48. int x=sorted[j].second;
  49. A[x]=tree.segsum(dfn[x],dfn[x]+numpst[x]-1);
  50. B[x]=tree.segsum(1,N)-A[x];
  51. }
  52. for(;i>j;i--) tree.change(dfn[sorted[i].second],1);
  53. }
  54. }
  55. int tim=0;//时间
  56. void DFS(int x){
  57. tim++;
  58. dfn[x]=tim;
  59. C[x]=tree.segsum(delic[x]+1,numval);
  60. tree.change(delic[x],1);
  61. numpst[x]=1;//子树上节点个数
  62. for(int i=0;i<c[x].size();i++){
  63. DFS(c[x][i]);
  64. numpst[x]+=numpst[c[x][i]];
  65. }
  66. tree.change(delic[x],-1);
  67. }
  68. void init(void){
  69. scanf("%d",&N);
  70. for(int i=2;i<=N;i++){
  71. scanf("%d",&father[i]);
  72. c[father[i]].push_back(i);
  73. }
  74. vector<int> atp;
  75. for(int i=1;i<=N;i++) scanf("%d",&delic[i]),atp.push_back(delic[i]);
  76. sort(atp.begin(),atp.end());
  77. numval=0;
  78. for(int i=0;i<atp.size();i++) if(!i||atp[i]!=atp[i-1]) dlcmp[atp[i]]=++numval;//离散化
  79. for(int i=1;i<=N;i++) delic[i]=dlcmp[delic[i]];//修改美味值
  80. tree.clear(numval);//以权值为下标的树状数组
  81. }
  82. int main(){
  83. freopen("treesfruits.in","r",stdin);
  84. freopen("treesfruits.out","w",stdout);
  85. init();
  86. DFS(1);
  87. work();
  88. for(int i=1;i<=N;i++) printf("%d %d %d\n",A[i],B[i],C[i]);
  89. return 0;
  90. }