AC日记——[HNOI2014]世界树 bzoj 3572
3572
思路:
虚树+乱搞;
代码:
#include <bits/stdc++.h>
using namespace std;
#define maxn 300005
#define INF 0x3f3f3f3f
struct KiType {
int id,key;
bool operator<(const KiType pos)const
{
return key<pos.key;
}
};
struct KiType ki[maxn];
int bel[maxn],dis[maxn],size[maxn],li[maxn],ri[maxn],lar[maxn],f[maxn];
int head[maxn],E[maxn<<],V[maxn<<],cnt,id[maxn],id_[maxn],deep[maxn];
int top[maxn],ai[maxn],sta[maxn],sum[maxn],n,m;
int W[maxn<<];
bool vis[maxn],if_[maxn];
queue<int>que;
inline void in(int &now)
{
char Cget=getchar();now=;
while(Cget>''||Cget<'')Cget=getchar();
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
}
inline void edge_add(int u,int v)
{
E[++cnt]=head[u],V[cnt]=v,head[u]=cnt;
E[++cnt]=head[v],V[cnt]=u,head[v]=cnt;
}
inline void edge_add1(int u,int v)
{
if(deep[u]<deep[v]) swap(u,v);
int w=deep[u]-deep[v];
// printf("%d %d %d\n",u,v,w);
E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt;
E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt;
}
void dfs1(int now,int fa)
{
f[now]=fa,deep[now]=deep[fa]+,size[now]=;
for(int i=head[now];i;i=E[i])
{
if(V[i]==fa) continue;
dfs1(V[i],now),size[now]+=size[V[i]];
if(size[V[i]]>size[lar[now]]) lar[now]=V[i];
}
}
void dfs2(int now,int chain)
{
top[now]=chain,id[now]=++cnt,id_[cnt]=now;
if(lar[now]) dfs2(lar[now],chain);
for(int i=head[now];i;i=E[i])
{
if(V[i]==lar[now]||V[i]==f[now]) continue;
dfs2(V[i],V[i]);
}
ri[now]=cnt;
}
inline int find(int x,int y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
x=f[top[x]];
}
return deep[x]<deep[y]?x:y;
}
inline int up(int now,int to)
{
while(to<deep[top[now]]) now=f[top[now]];
return id_[id[now]-deep[now]+to];
}
void Count(int now,int fa)
{
int pos,pos_;
if(!fa||bel[fa]==bel[now]) goto cur;
pos=deep[now]-deep[fa]-;
if(pos)
{
pos_=(dis[fa]+pos+dis[now]+(bel[fa]<bel[now]?:))>>;
pos_=up(now,pos_-dis[fa]+deep[fa]+);
pos_=size[pos_]-size[now];
sum[bel[now]]+=pos_,sum[bel[fa]]-=pos_;
}
cur:
sum[bel[now]]+=size[now];
for(int i=head[now];i;i=E[i])
{
if(V[i]==fa) continue;
sum[bel[now]]-=size[V[i]];
Count(V[i],now);
}
}
void clear(int now,int fa)
{
for(int i=head[now];i;i=E[i])
{
if(fa==V[i]) continue;
clear(V[i],now);
}
head[now]=,sum[now]=,dis[now]=,vis[now]=false;
bel[now]=,dis[now]=INF;
}
int main()
{
freopen("worldtree.in","r",stdin);
freopen("worldtree.out","w",stdout);
in(n);int u,v;
for(int i=;i<n;i++) in(u),in(v),edge_add(u,v);
cnt=,dfs1(,),dfs2(,),memset(head,,sizeof(head));
in(m);
for(int i=;i<=n;i++) dis[i]=INF;
while(m--)
{
in(u),cnt=;
for(int i=;i<=u;i++)
{
in(ki[i].id);
ai[i]=ki[i].id;
dis[ki[i].id]=;
vis[ki[i].id]=true;
if_[ki[i].id]=true;
que.push(ki[i].id);
bel[ki[i].id]=ki[i].id;
ki[i].key=id[ki[i].id];
}
sort(ki+,ki+u+),v=,sta[v]=;
for(int i=;i<=u;i++)
{
int now=ki[i].id,pos=;
if(sta[v]==now) continue;
while(id[now]<li[sta[v]]||id[now]>ri[sta[v]])
{
if(pos) edge_add1(pos,sta[v]);
pos=sta[v],v--;
}
if(pos)
{
int lca=find(pos,now);
if(lca!=pos) edge_add1(pos,lca);
if(lca!=sta[v]) sta[++v]=lca;
}
sta[++v]=now;
}
while(v>) edge_add1(sta[v],sta[v-]),v--;
while(!que.empty())
{
int now=que.front();que.pop(),if_[now]=false;
for(int i=head[now];i;i=E[i])
{
if(dis[V[i]]>dis[now]+W[i])
{
dis[V[i]]=dis[now]+W[i];
bel[V[i]]=bel[now];
if(!if_[V[i]]) if_[V[i]]=true,que.push(V[i]);
}
else if(dis[V[i]]==dis[now]+W[i])
{
if(bel[now]<bel[V[i]])
{
bel[V[i]]=bel[now];
if(!if_[V[i]]) if_[V[i]]=true,que.push(V[i]);
}
}
}
}
Count(,);
for(int i=;i<u;i++) printf("%d ",sum[ai[i]]);
printf("%d \n",sum[ai[u]]);
clear(,);
}
return ;
}
AC日记——[HNOI2014]世界树 bzoj 3572的更多相关文章
- AC日记——[Hnoi2017]影魔 bzoj 4826
4826 思路: 主席树矩阵加减+单调栈预处理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 ...
- AC日记——[LNOI2014]LCA bzoj 3626
3626 思路: 离线操作+树剖: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #defin ...
- AC日记——[ZJOI2012]网络 bzoj 2816
2816 思路: 多个LCT: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 10005 #define l ...
- AC日记——[SCOI2009]游戏 bzoj 1025
[SCOI2009]游戏 思路: 和为n的几个数最小公倍数有多少种. dp即可: 代码: #include <bits/stdc++.h> using namespace std; #de ...
- AC日记——NOI2016区间 bzoj 4653
4653 思路: 线段树,指针滑动: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1000005 #def ...
- AC日记——Rmq Problem bzoj 3339
3339 思路: 恶心: 代码: #include <cstdio> #include <cstring> #include <iostream> #include ...
- AC日记——[HNOI2008]越狱 bzoj 1008
1008 思路: 越狱情况=总情况-不越狱情况: 代码: #include <cstdio> #include <cstring> #include <iostream& ...
- AC日记——[FJOI2007]轮状病毒 bzoj 1002
1002 思路: 打表找规律: dp[i]=dp[i-1]*3-dp[i-2]+2; 套个高精就a了: 代码: #include <cstdio> #include <cstring ...
- AC日记——[Ahoi2013]作业 bzoj 3236
3236 思路: 莫队+树状数组维护: 代码: #include <cmath> #include <cstdio> #include <cstring> #inc ...
随机推荐
- 淘淘搜索结果中image属性中有多张图片的处理
solr引擎查询某一个 商品后的结果中,image字段中如果有多张图片路径(用逗号隔开)时,前台会不 显示图片,解决方法如下: package com.taotao.portal.pojo; publ ...
- 15ecjtu校赛1006 (dfs容斥)
Problem Description 在平面上有一个n*n的网格,即有n条平行于x轴的直线和n条平行于y轴的直线,形 成了n*n个交点(a,b)(1<=a<=n,1<=b<= ...
- String和StringBuffer的一点研究
转载自:http://www.cnblogs.com/heshan664754022/archive/2013/03/15/2961463.html 首先请看下下面的这几个输出的结果,请仔细考虑,不要 ...
- Spring注解@Resource和@Autowired的区别
@Resource和@Autowired都是用来做bean的依赖注入的,两者都可以写在字段和setter方法上. java为我们提供了 javax.annotation.Resource这个注解. s ...
- 图论:Prufer编码
BZOJ1211:使用prufer编码解决限定结点度数的树的计数问题 首先学习一下prufer编码是干什么用的 prufer编码可以与无根树形成一一对应的关系 一种无根树就对应了一种prufer编码 ...
- Scala环境安装设置
Scala语言可以安装在任何类UNIX或Windows系统.要安装Scala,必须先安装Java1.5或更高版本安装在计算机上. Windows上安装Scala: 步骤(1):JAVA设置: 首先,必 ...
- 【转】js JavaScript 的性能优化:加载和执行
JavaScript 的性能优化:加载和执行 转自:https://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/ 随着 Web2.0 技术的 ...
- go通过名称来调用对应的方法
仅仅是为了学习go语言中的反射. package main import ( "errors" "fmt" "reflect" ) func ...
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- IT培训班123
最近20年,IT行业一直处于上升期,程序员的工资越来越高了,年薪几十万的程序员大有人在.根据国家统计局发布的2016年各行业平均工资报表,程序员已经是工资最高的一个群体,超过了金融行业. IT行业的火 ...