51nod 1297 管理二叉树
来源:互联网 发布:纯t是什么意思网络用语 编辑:程序博客网 时间:2024/05/23 11:23
1297 管理二叉树
题目来源: HackerRank
基准时间限制:3 秒 空间限制:131072 KB 分值: 640 难度:8级算法题
收藏
关注
一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}。我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束。在每一个添加操作后,输出T上每对节点之间的距离之和。
例如:4 7 3 1 8 2 6 5。最终的二叉树为:
4
/ \
3 7
/ / \
1 6 8
\ /
2 5
节点两两之间的距离和 = 6+5+5+4+3+2+1+5+4+4+3+2+1+4+3+3+2+1+3+2+2+1+2+1+1+2+1+3 = 76
Input
第1行:1个数N。(1 <= N <= 100000)第2 - N + 1行:每行1个数,对应排列的元素。(1 <= ai <= N)
Output
输出共N行,每行1个数,对应添加当前元素后,每对节点之间的距离之和。
Input示例
847318265
Output示例
0141020355276
李陶冶 (题目提供者)
【分析】
动态点分治
预处理出来各个节点与各层分治中心的距离等信息,按时间顺序逐个插入点统计答案。
【代码】
//51nod 1297 管理二叉树 #include<bits/stdc++.h>#define inf 1e6#define ll long long#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(int i=j;i<=k;i++)using namespace std;const int mxn=150005;set <int> s;bool vis[mxn];ll ans,tmp;int n,m,T,cnt,tot,root;int head[mxn],ch[mxn][2];ll ans1[mxn],ans2[mxn],num[mxn];int a[mxn],dep[mxn],pre[mxn],nxt[mxn];int anc[mxn][22],dis[mxn][22],mx[mxn],sz[mxn];struct edge {int to,next;} f[mxn<<1];inline void add(int u,int v){f[++cnt].to=v,f[cnt].next=head[u],head[u]=cnt;f[++cnt].to=u,f[cnt].next=head[v],head[v]=cnt;}inline void dfs_size(int u,int fa){sz[u]=1,mx[u]=0;for(int i=head[u];i;i=f[i].next){int v=f[i].to;if(v==fa || vis[v]) continue;dfs_size(v,u);sz[u]+=sz[v];mx[u]=max(mx[u],sz[v]);}mx[u]=max(mx[u],tot-sz[u]);if(mx[u]<mx[root]) root=u;}inline void dfs_dis(int u,int fa,int Anc,ll Dis){dep[u]++;anc[u][dep[u]]=Anc;dis[u][dep[u]]=Dis;for(int i=head[u];i;i=f[i].next){int v=f[i].to;if(v==fa || vis[v]) continue;dfs_dis(v,u,Anc,Dis+1);}}inline void dfs(int u){mx[root=0]=inf;dfs_size(u,0);dfs_dis(root,root,root,0);dep[root]--,vis[root]=1;for(int i=head[root];i;i=f[i].next){int v=f[i].to;if(vis[v]) continue;dfs_size(v,0); tot=sz[v],dfs(v);}}inline void solve(int u){tmp=ans1[u];for(int i=dep[u];i>1;i--){ll Dis=dis[u][i-1];tmp+=ans1[anc[u][i-1]]-ans2[anc[u][i]];tmp+=Dis*(num[anc[u][i-1]]-num[anc[u][i]]);}ans+=tmp,num[u]++;for(int i=dep[u];i>1;i--){ll Dis=dis[u][i-1];ans1[anc[u][i-1]]+=Dis;ans2[anc[u][i]]+=Dis;num[anc[u][i-1]]++;}printf("%lld\n",ans);}inline void build(){set <int>::iterator pr,nt;s.insert(a[1]);fo(i,2,n){s.insert(a[i]);pr=nt=s.lower_bound(a[i]);if(nt!=s.end()){nt++;if(nt!=s.end()) nxt[a[i]]=(*nt);}if(pr!=s.begin()) pr--,pre[a[i]]=(*pr);}fo(i,2,n){int u=a[i];if(!pre[u] || ch[pre[u]][1]){ch[nxt[u]][0]=u;add(nxt[u],u);//printf("connect=[%d,%d]\n",nxt[u],u);continue;}if(!nxt[u] || ch[nxt[u]][0]){ch[pre[u]][1]=u;add(pre[u],u);//printf("connect=[%d,%d]\n",pre[u],u);}}}int main(){scanf("%d",&n);fo(i,1,n) scanf("%d",&a[i]);build();tot=n,dfs(1);fo(i,1,n) anc[i][++dep[i]]=i;fo(i,1,n) solve(a[i]);return 0;}
阅读全文
0 0
- [51nod 1297]管理二叉树
- 【51NOD 1297】管理二叉树
- 51nod 1297 管理二叉树
- 51nod 1297 管理二叉树
- 51nod 1297 管理二叉树 (树分治)
- 51nod 1260 排列与二叉树
- 51nod-1603 限高二叉排列树
- 51nod 1603 限高二叉排列树
- 51Nod-1603-限高二叉排列树
- 51Nod-1619-完全二叉树的方差
- 51nod 1603 限高二叉排列树 计数dp
- 51nod1297 管理二叉树
- 【51nod1297】【管理二叉树】【点分治】
- 51nod 1603 限高二叉排列树(求补思想->DP)
- 51nod 1297
- 51Nod-1353-树
- 51nod 1631 线段树
- 51nod 1364 线段树
- 欢迎使用CSDN-markdown编辑器
- 字符串拼接string.format新语法
- linux下查看so文件的信息
- 关于js的消息提醒
- spring Spring StateMachine状态机
- 51nod 1297 管理二叉树
- 使用ajax实现页面跳转
- ucos II 任务延时函数
- 高通项目 首次开机后apk随机报错
- Tomcat7配置数据源
- 安装curl支持http2.0的步骤 及nghttp2安装 nghttp2的python模组
- 永远不要打探别人工资
- Python shuffle() 函数
- Ubuntu Linux 安装 .7z 解压和压缩文件