YbtOJ#662-交通运输【线段树合并,树状数组】

正题

题目链接:http://www.ybtoj.com.cn/contest/122/problem/2


题目大意

给出nnn个点的一棵有根树,对于每个xxx求,删除点xxx后修改某个点的父节点(修改前该点必须有父节点)后最小化最大联通块大小。


解题思路

删掉一个点后肯定是最大的那个联通块分一个子树给最小的那个联通块。
maxsmaxsmaxs表示最大的联通块,rmaxrmaxrmax表示次大的联通块,minsminsmins表示最小的联通块,那么答案一定在[rmax,maxs][rmax,maxs][rmax,maxs]之间,而且最小化最大值我们可以考虑二分

然后要分成两种情况
若最大联通块是某一个儿子的子树,这种情况很好处理,我们用线段树合并计算出每个子树可以取的子树大小(不包括它本身),然后判断一下是否有大小在[maxs−mid,mid−mins][maxs-mid,mid-mins][maxsmid,midmins]中的子树就好了。

若最大联通块是父节点所在联通块的子树,这种情况比较麻烦,我们需要把点分成两种,一种是在xxx到根节点路径上的,一种是不在那个上面的。
用树状数组记录一下在xxx到根节点路径上的子树大小,然后用总共的减去树状数组的和之前线段树那个在xxx子树内的就是不在到根节点路径上的,这些和之前那样查询就好了。
剩下在到根路径上的节点的子树大小都减少了sizxsiz_xsizx,我们将查询的区间右移sizxsiz_xsizx位就好了,用刚刚那个树状数组就好了

时间复杂度O(nlog⁡2n)O(n\log^2 n)O(nlog2n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
using namespace std;
const int N=1e5+10;
struct node{int to,next;
}a[N];
int n,tot,fa[N],deg[N],ls[N],rt[N],siz[N],ans[N];
struct SegTree{int w[N<<5],ls[N<<5],rs[N<<5],cnt;int Change(int x,int L,int R,int pos){int p=++cnt;w[p]=w[x]+1;if(L==R)return p;int mid=(L+R)>>1;if(pos<=mid)ls[p]=Change(ls[x],L,mid,pos),rs[p]=rs[x];else rs[p]=Change(rs[x],mid+1,R,pos),ls[p]=ls[x];return p;}int Ask(int x,int L,int R,int l,int r){if(!x)return 0;if(L==l&&R==r)return w[x];int mid=(L+R)>>1;if(r<=mid)return Ask(ls[x],L,mid,l,r);if(l>mid)return Ask(rs[x],mid+1,R,l,r);return Ask(ls[x],L,mid,l,mid)+Ask(rs[x],mid+1,R,mid+1,r);}int Merge(int x,int y){if(!x||!y)return x+y;int p=++cnt;w[p]=w[x]+w[y];ls[p]=Merge(ls[x],ls[y]);rs[p]=Merge(rs[x],rs[y]);return p;}
}T;
struct TreeBinary{int t[N];void Change(int x,int val){while(x<=n){t[x]+=val;x+=lowbit(x);}return;}int Ask(int x){int ans=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;}
}B,D;
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void dfs(int x){siz[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;dfs(y);siz[x]+=siz[y];rt[x]=T.Change(rt[x],1,n,siz[y]);rt[x]=T.Merge(rt[x],rt[y]);}D.Change(siz[x],1);return;
}
int epe(int L,int R,int x){if(L>R)return 0;return D.Ask(R)-D.Ask(L-1)+B.Ask(R+siz[x])-B.Ask(L+siz[x]-1)-T.Ask(rt[x],1,n,L,R);
}
void work(int x){if(x==36449)x++,x--;if(deg[x]<2){ans[x]=max(siz[1]-siz[x],siz[a[ls[x]].to]);return;}int p=0,mins=n,maxs=0,rmax=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(siz[y]>maxs)rmax=maxs,maxs=siz[y],p=y;else if(siz[y]>rmax)rmax=siz[y];mins=min(mins,siz[y]);}if(siz[1]-siz[x]>maxs){rmax=maxs;maxs=siz[1]-siz[x];mins=min(mins,siz[1]-siz[x]);int L=rmax,R=maxs-1;while(L<=R){int mid=(L+R)>>1;int l=maxs-mid,r=mid-mins;if(epe(l,r,x))R=mid-1;else L=mid+1;}ans[x]=L;return;}else if(fa[x]){if(siz[1]-siz[x]>rmax)rmax=siz[1]-siz[x];mins=min(mins,siz[1]-siz[x]);}int L=rmax,R=maxs-1;while(L<=R){int mid=(L+R)>>1;int l=maxs-mid,r=mid-mins;if(T.Ask(rt[p],1,n,l,r))R=mid-1;else L=mid+1;}ans[x]=L;return;
}
void calc(int x){D.Change(siz[x],-1);work(x);B.Change(siz[x],1);for(int i=ls[x];i;i=a[i].next)calc(a[i].to);B.Change(siz[x],-1);D.Change(siz[x],1);
}
int main()
{freopen("traffic.in","r",stdin);freopen("traffic.out","w",stdout);scanf("%d",&n);for(int i=2;i<=n;i++){scanf("%d",&fa[i]);deg[fa[i]]++;deg[i]++;addl(fa[i],i);}dfs(1);D.Change(siz[1],-1);work(1);B.Change(siz[1],1);for(int i=ls[1];i;i=a[i].next)calc(a[i].to);for(int i=1;i<=n;i++)printf("%d\n",ans[i]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EOJ Monthly 2020.9 Sponsored by TuSimple E. 加密的情书

E加密的情书 本人太菜&#xff0c;只会签到 题意&#xff1a; 一个多位数可以通过加密变成个位数&#xff0c;加密方式为&#xff1a;各个位数上的数相加&#xff0c;直到加成个位数 例如&#xff1a; 123 --》 1236 现在给出加密后的一串密文 问是否存在连续的自然数数列 l …

【线段树】Frog Traveler(CF751D)

正题 CF751D 题目大意 现在有n个点&#xff0c;当你在i时&#xff0c;可以向前跳 0∼ai0\sim a_i0∼ai​ 步&#xff0c;跳到j&#xff0c;然后向后走bjb_jbj​步&#xff0c;现在让你从n开始跳&#xff0c;回答跳到0的最少步数 解题思路 设fif_ifi​为跳到i的最少步数&…

独立版Jexus配置SSL,支持https访问

一、申请证书【腾讯免费证书】二、验证DNS&#xff0c;即解析域名。记录类型选择 TXT &#xff0c;主机记录与证书上的主机记录保持一致&#xff0c;记录值也与证书上的记录值保持一致三、等待DNS验证与CA轮询&#xff0c;轮询成功后即可下载证书四、Jexus用到的是Nginx中的证书…

codeforces1437 E. Make It Increasing——最长上升子序列

E. Make It Increasing 首先让aiai−ia_ia_i-iai​ai​−i这样可以是严格单增变成单调增。 参考官方题解 首先不难得出如果我们根据不同修改的位置分割成若干段&#xff0c;那么若干段是互不影响的&#xff0c;我们只需要求出每一个若干段修改次数的最小值。 如果当前考虑l~r…

P4451-[国家集训队]整数的lqp拆分【生成函数,特征方程】

正题 题目链接:https://www.luogu.com.cn/problem/P4451 题目大意 给出nnn&#xff0c;对于所有满足∑i1main\sum_{i1}^ma_in∑i1m​ai​n且∀ai∈N\forall a_i\in N^∀ai​∈N的序列求 ∑m1∞∏i1mFbiai\sum_{m1}^{\infty}\prod_{i1}^mFbi_{a_i}m1∑∞​i1∏m​Fbiai​​ 其…

莫比乌斯反演+例题

参考1 参考2 参考3 问题引入&#xff1a; 入门题 给定N和M和D&#xff0c;求满足1<x<N,1<y<M且gcd(x,y)D的点对(x,y)的个数 1<N,M<1000000 莫比乌斯函数 μ μ(n) 1 , n1 μ(n) (-1)k, np1 * p2 * … * Pk &#xff08;x有奇数个质因子时为-1&#xff…

【线段树】Optimal Insertion(CF751E)

正题 CF751E 题目大意 给你一个数组a和一个集合b&#xff0c;现在让你把b中的数插入a&#xff0c;使得逆序对最少 解题思路 先计算a中的逆序对 对于b和a的逆序对&#xff0c;可以对数字进行排序&#xff0c;用线段树存下放每个位置的最小代价&#xff0c;然后直接求最小值 …

.net core通过多路复用实现单服务百万级别RPS吞吐

多路复用其实并不是什么新技术&#xff0c;它的作用是在一个通讯连接的基础上可以同时进行多个请求响应处理。对于网络通讯来其实不存在这一说法&#xff0c;因为网络层面只负责数据传输&#xff1b;由于上层应用协议的制订问题&#xff0c;导致了很多传统服务并不能支持多路复…

2020 China Collegiate Programming Contest Weihai Site补题部分

A. Golden Spirit 签到题&#xff0c;首先把所有老人带到对岸&#xff0c;然后在对休息讨论一下即可。 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<…

P5110-块速递推【特征方程,分块】

正题 题目链接:https://www.luogu.com.cn/problem/P5110 题目大意 数列aaa满足 an233an−1666an−2,a00,a11a_n233a_{n-1}666a_{n-2},a_00,a_11an​233an−1​666an−2​,a0​0,a1​1 TTT组询问给出nnn求ana_nan​ 1≤T≤51071\leq T\leq 5\times 10^71≤T≤5107&#xff0c;…

I - Washing clothes

题意&#xff1a; 有n个人会在某时间段来洗衣服&#xff0c;但是只有一台洗衣机&#xff0c;当洗衣机被用时其他人只能手洗&#xff0c;手洗时间为y&#xff08;题目给定&#xff09;&#xff0c;洗衣机的时间为x&#xff0c;x∈[1,y]&#xff0c;问当x分别为[1,y]时&#xff…

【LCT】历史(P4338)

正题 P4338 题目大意 有一棵树&#xff0c;告诉你每个点access的次数&#xff08;带修改&#xff09;&#xff0c;问实链切换的最多次数 解题思路 先考虑离线的做法&#xff1a; 对于点 x&#xff0c;其不同儿子的子树access会使实链切换&#xff08;对于点 x access 同理&…

微软官宣:史上最贵开发工具 75亿美金收购GitHub

微软副总裁红衣主教Scott Gu今天的一封邮件结束了这笔软件历史上最大收购案&#xff0c;微软给全球开发人员的开源代码仓库GitHub投入了75亿美金&#xff0c;确保这一平台的持续健康发展。GitHub为啥愿意被收购&#xff1f;“软件工程这个事情&#xff0c;从来就不是一笔好生意…

codeforces1438 E.Yurii Can Do Everything

E.Yurii Can Do Everything 官方题解 按照题解的意思&#xff0c;由于满足此条件的数量不多&#xff0c;因此可以挖掘某些信息进行暴力。 考虑一个good subarray&#xff1a;[al,al1,…,ar−1,ar][a_l,a_{l1},\dots,a_{r-1},a_r][al​,al1​,…,ar−1​,ar​] 按照题目意思满…

YbtOJ#791-子集最值【三维偏序】

正题 题目链接:http://www.ybtoj.com.cn/contest/123/problem/1 题目大意 给出333个长度为nnn的排列A,B,CA,B,CA,B,C。然后一个下标集合SSS的三元组是 (max{Ai},max{Bi},max{Ci})(i∈S)(max\{A_i\},max\{B_i\},max\{C_i\})(i\in S)(max{Ai​},max{Bi​},max{Ci​})(i∈S) 求…

【主席树】更为厉害(P3899)

正题 P3899 题目大意 给你一棵树&#xff0c;对于每次询问&#xff0c;给出x,k&#xff0c;问你有多少个三元组(y,z)满足x,y,z不同&#xff0c;x,y之间的距离小于k&#xff0c;且x,y都是z的祖先 解题思路 若y的深度小于x&#xff0c;那么一定在x到根节点的路径上&#xff0c…

人工智能——图像分析第二期练习

又和同学肝了半个上午&#xff08;主要是一二节有课&#xff09;&#xff0c;完成了天气图像识别的第二期练习 一开始几个题不难&#xff0c;挺简单的&#xff0c;到后面出现HOG特征拟合svm模型&#xff0c;HOG提取特征&#xff0c;又是现学内容 HOG特征的维数用cv2.HOGDescrip…

C# 中使用面向切面编程(AOP)中实践代码整洁

1. 前言最近在看《架构整洁之道》一书&#xff0c;书中反复提到了面向对象编程的 SOLID 原则&#xff08;在作者的前一本书《代码整洁之道》也是被大力阐释&#xff09;&#xff0c;而面向切面编程&#xff08;Aop&#xff09;作为面向对象编程的有力补充&#xff0c;对实践整洁…

AtCoder Beginner Contest 183 总结

本来懒得写了&#xff0c;不过第一次AK还是记录一下吧 A - ReLU ABC的签到题就是友好 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<stack> #inc…

【数论】ZAP-Queries(P3455)

正题 P3455 题目大意 有T组询问&#xff0c;每组询问给出n,m,c&#xff0c;求∑i1n∑j1m[(i,j)c]\sum_{i1}^{n}\sum_{j1}^{m}[(i,j)c]i1∑n​j1∑m​[(i,j)c] 解题思路 可以先对n,m除c这样就使得求出的数都有c的因子&#xff0c;得到式子如下 ∑i1n∑j1m[(i,j)1]∑i1n∑j1m∑…