解题:HNOI 2014 世界树
首先建虚树
DFS求虚树上每个点所属的点和到它所属点的距离,然后在=考虑虚树所有的边(对应原树一条链)。如果两个端点所属节点不同就倍增出分界点统计答案,否则不用管(之后会统计到的);注意根节点特殊讨论。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=,inf=1e9;
int T,n,m,t1,t2,cnt,tot,top;
int p[N],noww[N],goal[N];
int siz[N],dep[N],dfn[N],upt[N][K],oth[N][K];
int a[N],b[N],c[N],d[N],bel[N],stk[N],ans[N];
bool cmp(int a,int b)
{
return dfn[a]<dfn[b];
}
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth,int dth)
{
siz[nde]=,dep[nde]=dth;
upt[nde][]=fth,dfn[nde]=++tot;
for(int i=;i<=&&upt[nde][i-];i++)
upt[nde][i]=upt[upt[nde][i-]][i-];
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
DFS(goal[i],nde,dth+),siz[nde]+=siz[goal[i]];
}
void Calc(int nde,int fth)
{
oth[nde][]=siz[fth]-siz[nde];
for(int i=;i<=&&upt[nde][i-];i++)
oth[nde][i]=oth[nde][i-]+oth[upt[nde][i-]][i-];
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth) Calc(goal[i],nde);
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;dep[x]!=dep[y];i--)
if(dep[upt[x][i]]>=dep[y]) x=upt[x][i];
if(x==y) return x;
for(int i=;~i;i--)
if(upt[x][i]!=upt[y][i])
x=upt[x][i],y=upt[y][i];
return upt[x][];
}
int Dis(int x,int y)
{
int lca=LCA(x,y);
return dep[x]+dep[y]-*dep[lca];
}
bool Check(int a,int b,int d)
{
return c[a]+d<c[b]||(c[a]+d==c[b]&&bel[a]<bel[b]);
}
void Insert(int nde)
{
if(!top) stk[++top]=nde;
else
{
int lca=LCA(nde,stk[top]);
if(lca!=stk[top])
{
while(top>&&dfn[lca]<=dfn[stk[top-]])
Link(stk[top-],stk[top]),top--;
if(dfn[lca]<dfn[stk[top]])
Link(lca,stk[top]),top--;
if(lca!=stk[top])
stk[++top]=lca;
}
stk[++top]=nde;
}
}
int Upt(int nde,int gal)
{
int ret=;
for(int i=;~i;i--)
if(gal&(<<i))
ret+=oth[nde][i],nde=upt[nde][i];
return ret;
}
void DFS1(int nde)
{
if(!bel[nde]) c[nde]=inf;
for(int i=p[nde];i;i=noww[i])
{
int g=goal[i],dd=dep[g]-dep[nde]; DFS1(g);
if(Check(g,nde,dd)) c[nde]=c[g]+dd,bel[nde]=bel[g];
}
}
void DFS2(int nde,int lst)
{
int dd=dep[nde]-dep[lst];
if(lst&&Check(lst,nde,dd))
c[nde]=c[lst]+dd,bel[nde]=bel[lst];
for(int i=p[nde];i;i=noww[i])
DFS2(goal[i],nde),d[nde]+=d[goal[i]];
if(!lst) ans[bel[nde]]+=n-d[nde];
else if(bel[nde]!=bel[lst])
{
int cut=c[nde]+c[lst]+dd,chk=cut%||bel[nde]<bel[lst],tmp;
tmp=Upt(nde,cut/-c[nde]-(chk^));
ans[bel[nde]]+=siz[nde]-d[nde]+tmp,d[nde]=siz[nde]+tmp;
}
}
void Clear(int nde)
{
for(int i=p[nde];i;i=noww[i])
Clear(goal[i]);
bel[nde]=p[nde]=c[nde]=d[nde]=;
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d%d",&t1,&t2),Link(t1,t2),Link(t2,t1);
DFS(,,),Calc(,),memset(p,,sizeof p);
scanf("%d",&T);
while(T--)
{
scanf("%d",&m),cnt=top=;
for(int i=;i<=m;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(a+,a++m,cmp); stk[top=]=a[],bel[a[]]=a[];
for(int i=;i<=m;i++) Insert(a[i]),bel[a[i]]=a[i];
while(top>) Link(stk[top-],stk[top]),top--;
DFS1(stk[]),DFS2(stk[],);
for(int i=;i<=m;i++)
printf("%d ",ans[b[i]]),ans[b[i]]=;
Clear(stk[]),puts("");
}
return ;
}
解题:HNOI 2014 世界树的更多相关文章
- 数据结构(虚树,动态规划):HNOI 2014 世界树
Hnoi2014 世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平 ...
- [HNOI 2014]世界树
Description 题库链接 给出一棵 \(n\) 个节点的树, \(q\) 次询问,每次给出 \(k\) 个关键点.树上所有的点会被最靠近的关键点管辖,若距离相等则选编号最小的那个.求每个关键点 ...
- HNOI 2014 米特运输(图论)
HNOI 2014 米特运输 题目大意 给一棵树,每个点有自己的权值,要求更改一些点的权值,使得整棵树满足两个条件: 同一个父亲的所有子节点权值相同 父节点的取值为所有子节点的和 答案输出最少要更改的 ...
- HNOI 2014
D1T1:画框 frame 题意:给你两个n阶正整数方阵,请你求最大的\( \sum_{i = 1}^{n} A_{i, p_i}\times \sum_{i = 1}^{n} B_{i, p_i} ...
- 图论(KM算法,脑洞题):HNOI 2014 画框(frame)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABPoAAANFCAIAAABtIwXVAAAgAElEQVR4nOydeVxTV/r/n9ertaJEC4
- [HNOI 2014]画框
Description 题库链接 \(T\) 组询问,每组询问给你个 \(2\times N\) 的带权二分图,两个权值 \(a,b\) ,让你做匹配使得 \[\sum a\times \sum b\ ...
- [HNOI 2014]江南乐
Description 题库链接 给你指定一个数 \(f\) ,并给你 \(T\) 组游戏,每组有 \(n\) 堆石子, \(A,B\) 两人轮流对石子进行操作,每次你可以选择其中任意一堆数量不小于 ...
- [HNOI 2014]道路堵塞
Description A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国 交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有 ...
- [HNOI 2014]米特运输
Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储 存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市 ...
随机推荐
- Android WebView漏洞(转)
一.漏洞描述 近期,微信等多款安卓流行应用曝出高危挂马漏洞:只要点击好友消息或朋友圈中的一条网址,手机就会自动执行黑客指令,出现被安装恶意扣费软件.向好友 发送欺诈短信.通讯录和短信被窃取等严重后果. ...
- WPF 嵌入winform 控件
引入 WindowsFormsIntegration.dll 和 System.Windows.Forms.dll <Window x:Class="wgscd.Window1 ...
- 20155226 《网络对抗》exp6信息搜集与漏洞扫描
20155226 <网络对抗>exp6信息搜集与漏洞扫描 实验后回答问题 哪些组织负责DNS,IP的管理? 目前域名机构主要包括ICANN理事会和CNNIC. Internet 域名与地址 ...
- Voronoi图与Delaunay三角剖分
详情请见[ZJOI2018]保镖 题解随笔 - 99 文章 - 0 评论 - 112
- HTML 样式 (style) 实例
77.HTML 样式 (style) 实例HTML 的 style 属性style 属性的作用: 提供了一种改变所有 HTML 元素的样式的通用方法. 样式是 HTML 4 引入的,它是一种新的首选的 ...
- Salesforce随笔: 将Visualforce Page渲染为PDF文件(Render a Visualforce Page as a PDF File)
参照 : Visualforce Developer Guide 第60页 <Render a Visualforce Page as a PDF File> 你可以用PDF渲染服务生成一 ...
- Win环境 Android Studio使用Git 教程 ( 生成SSH key )
Github和码云都提供SSH协议,即用户可以用公钥认证方式连接到码云的SSH服务器.这就需要生成并部署SSH Key.下面就是我生成SSH Key的步骤,希望有所帮助: Git生成SSH key 在 ...
- SQL邮件服务(解决各种疑难杂症)+案例 + 使用SQLserver 邮件系统发送SQL代理作业执行警告
首先你需要知道你要做的几部: 1 每个数据库都有自己的 SERVICE BROKER 很多SQL SERVER内部服务依赖它 2 启动 SERVICE BROKER 需要 1 STOP 你的 SQL ...
- PAT甲题题解-1024. Palindromic Number (25)-大数运算
大数据加法给一个数num和最大迭代数k每次num=num+num的倒序,判断此时的num是否是回文数字,是则输出此时的数字和迭代次数如果k次结束还没找到回文数字,输出此时的数字和k 如果num一开始是 ...
- Python在函数中使用*和**接收元组和列表
http://blog.csdn.net/delphiwcdj/article/details/5746560