ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[atAGC023F]01 on Tree

2021-02-03 08:34:32  阅读:94  来源: 互联网

标签:01 return atAGC023F get int sum Tree pos find


对每一个节点维护一个序列,初始即自己(长度为1),并记$a_{i}$和$b_{i}$分别为第$i$个点序列上0和1的个数(也需要存储具体的序列)

考虑$\frac{b_{i}}{a_{i}}$最小中最深的非根节点(全局),其必然在其父亲之后选择,那么不妨将其与父亲合并,并将其的序列加入到父亲末尾(启发式合并)并利用$a_{i}$和$b_{i}$即可统计逆序对数量

(特别的,为了避免$a_{i}=0$,可以写成$\frac{b_{i}}{a_{i}+b_{i}}$)

另外,合并需要两个并查集,分别维护深度最小的点以及位置,以及set去找到$\frac{b_{i}}{a_{i}}$最小的点

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 set<pair<double,int> >s;
 5 deque<int>v[N];
 6 int n,x,fa[N],f[N],pos[N],sum[N][2];
 7 long long ans;
 8 int find(int k){
 9     if (k==f[k])return k;
10     return f[k]=find(f[k]);
11 }
12 double calc(int k){
13     return 1.0*sum[k][1]/(sum[k][0]+sum[k][1]);
14 }
15 pair<double,int> get(int k){
16     return make_pair(calc(pos[find(k)]),k);
17 }
18 void merge(int x,int y){
19     x=find(x),y=find(y);
20     f[y]=x;
21     int xx=x;
22     x=pos[x],y=pos[y];
23     deque<int>::iterator it;
24     if (v[x].size()<v[y].size()){
25         while (!v[x].empty()){
26             v[y].push_front(v[x].back());
27             if (v[x].back())ans+=sum[y][0];
28             v[x].pop_back();
29         }
30         sum[y][0]+=sum[x][0];
31         sum[y][1]+=sum[x][1];
32         pos[xx]=y;
33     }
34     else{
35         while (!v[y].empty()){
36             v[x].push_back(v[y].front());
37             if (!v[y].front())ans+=sum[x][1];
38             v[y].pop_front();
39         }
40         sum[x][0]+=sum[y][0];
41         sum[x][1]+=sum[y][1];
42         pos[xx]=x;
43     }
44 }
45 int main(){
46     scanf("%d",&n);
47     for(int i=2;i<=n;i++)scanf("%d",&fa[i]);
48     for(int i=1;i<=n;i++)f[i]=pos[i]=i;
49     for(int i=1;i<=n;i++){
50         scanf("%d",&x);
51         sum[i][x]++;
52         v[i].push_back(x);
53         if (i>1)s.insert(get(i));
54     }
55     for(int i=1;i<n;i++){
56         x=(*s.begin()).second;
57         set<pair<double,int> >::iterator it;
58         s.erase(s.begin());
59         int y=find(fa[x]);
60         if (y!=1)s.erase(get(y));
61         merge(fa[x],x);
62         if (y!=1)s.insert(get(y));
63     }
64     printf("%lld",ans);
65 }
View Code

 

标签:01,return,atAGC023F,get,int,sum,Tree,pos,find
来源: https://www.cnblogs.com/PYWBKTDA/p/14365134.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有