3572: [Hnoi2014]世界树 虚树+DP
来源:互联网 发布:mac系统怎么看文件大小 编辑:程序博客网 时间:2024/06/04 23:06
虚树裸题,正反DP一遍求答案。
写了一发rmqlca发现比倍增慢。。这个显然调用超过n次了啊。。为什么
bzoj傻逼样例没空格,样例在程序最下面。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 300005using namespace std;int n,m,Q,cnt,dfn,top,eul;int fa[N][20];int a[N],b[N],f[N],stack[N],point[N],rem[N],belong[N],deep[N],head[N],id[N],size[N],pos[N];int next[N<<1],list[N<<1];pair<int,int> ss[N<<1],st[N<<1][21];inline int read(){ int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f;}inline void insert(int x,int y){ next[++cnt]=head[x]; head[x]=cnt; list[cnt]=y;}void dfs(int x){ id[x]=++dfn; size[x]=1; ss[++eul]=make_pair(deep[x],x); pos[x]=eul; for (int i=1;(1<<i)<=deep[x];i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for (int i=head[x];i;i=next[i]) if (list[i]!=fa[x][0]) { fa[list[i]][0]=x; deep[list[i]]=deep[x]+1; dfs(list[i]); size[x]+=size[list[i]]; ss[++eul]=make_pair(deep[x],x); }}inline void make_st(){ for (int i=1;i<=eul;i++) st[i][0]=ss[i]; for (int j=1;j<=20;j++) for (int i=1;i<=eul;i++) if (i+(1<<j)-1<=eul) st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);}inline int lca(int x,int y){ int l=pos[x],r=pos[y]; if (l>r) swap(l,r); int k=log2(r-l+1); pair<int,int> ans=min(st[l][k],st[r-(1<<k)+1][k]); return ans.second;}inline bool cmp(int a,int b){ return id[a]<id[b];}inline int dis(int x,int y){ return deep[x]+deep[y]-(deep[lca(x,y)]<<1);}void dp1(int x){ point[++dfn]=x; rem[x]=size[x]; for (int i=head[x];i;i=next[i]) { dp1(list[i]); if (!belong[list[i]]) continue; int t1=dis(belong[list[i]],x),t2=dis(belong[x],x); if (t1<t2||!belong[x]||(t1==t2&&belong[list[i]]<belong[x])) belong[x]=belong[list[i]]; }}void dp2(int x){ for (int i=head[x];i;i=next[i]) { int t1=dis(belong[x],list[i]),t2=dis(belong[list[i]],list[i]); if (t1<t2||!belong[list[i]]||(t1==t2&&belong[x]<belong[list[i]])) belong[list[i]]=belong[x]; dp2(list[i]); }}void solve(int a,int b){ int x=b,mid=b; for (int i=18;~i;i--) if (deep[fa[x][i]]>deep[a]) x=fa[x][i]; rem[a]-=size[x]; if (belong[a]==belong[b]) { f[belong[a]]+=size[x]-size[b]; return; } for (int i=18;~i;i--) { if (deep[fa[mid][i]]<=deep[a]) continue; int t=fa[mid][i]; int t1=dis(belong[a],t),t2=dis(t,belong[b]); if (t1>t2||(t1==t2&&belong[a]>belong[b])) mid=t; } f[belong[a]]+=size[x]-size[mid]; f[belong[b]]+=size[mid]-size[b];}inline void query(){ m=read(); for (int i=1;i<=m;i++) a[i]=b[i]=read(); for (int i=1;i<=m;i++) belong[a[i]]=a[i]; sort(a+1,a+m+1,cmp); top=0; dfn=0; cnt=0; if (belong[1]!=1) stack[++top]=1; for (int i=1;i<=m;i++) { int t=a[i],f; while (top) { f=lca(stack[top],t); if (top>1&&deep[f]<deep[stack[top-1]]) insert(stack[top-1],stack[top]),top--; else if (deep[f]<deep[stack[top]]) { insert(f,stack[top]); top--; break; } else break; } if (stack[top]!=f) stack[++top]=f; stack[++top]=t; } while (top>1) insert(stack[top-1],stack[top]),top--; dp1(1); dp2(1); for (int i=1;i<=dfn;i++) for (int j=head[point[i]];j;j=next[j]) solve(point[i],list[j]); for (int i=1;i<=dfn;i++) f[belong[point[i]]]+=rem[point[i]]; for (int i=1;i<=m;i++) printf("%d ",f[b[i]]); puts(""); for (int i=1;i<=dfn;i++) head[point[i]]=rem[point[i]]=belong[point[i]]=f[point[i]]=0;}int main(){ n=read(); for (int i=1;i<n;i++) { int u=read(),v=read(); insert(u,v); insert(v,u); } dfs(1); make_st(); memset(head,0,sizeof(head)); Q=read(); while (Q--) query(); return 0;}/*102 13 24 35 46 17 38 39 410 1526 152 7 3 6 91848 7 10 352 9 3 5 81 9 3 1 4 1 1 10 1 1 3 5 4 1 3 1 1 */
0 0
- 【BZOJ】3572: [Hnoi2014]世界树【虚树DP】
- 3572: [Hnoi2014]世界树 虚树+DP
- bzoj 3572 [Hnoi2014]世界树 虚树 dp
- bzoj 3572 [Hnoi2014]世界树(虚树+DP)
- bzoj 3572: [Hnoi2014]世界树 (虚树+树形DP+LCA)
- [BZOJ3572][Hnoi2014]世界树 && 虚树+DP
- [ BZOJ3572 ] [ Hnoi2014 ] [ 虚树 ] [ 树形DP ] 世界树
- [BZOJ3572][HNOI2014]世界树-虚树+树形DP
- 3572: [Hnoi2014]世界树
- BZOJ 3572 [Hnoi2014]世界树 虚树
- 虚树(bzoj 3572: [Hnoi2014]世界树)
- [BZOJ3572][Hnoi2014]世界树(虚树+树形dp+二分+lca)
- 【BZOJ3572】【Hnoi2014】世界树 虚树
- bzoj 3572[HNOI2014]世界树
- BZOJ 3572: [Hnoi2014]世界树
- bzoj 3572: [Hnoi2014]世界树
- BZOJ3572: [Hnoi2014]世界树(虚树)
- bzoj3572: [Hnoi2014]世界树
- jpa
- next数组计算.
- Android中的Shape使用总结
- Lua和C++交互详细总结
- 堆排序的实现
- 3572: [Hnoi2014]世界树 虚树+DP
- 正交设计
- jenkins 自动构建项目
- maven "Generating project in Batch mode"问题的解决,archetype-catalog.xml
- 解决问题的三个办法,分先后
- HDU 2582 f(n) 数学
- C++ Prime 笔记
- 学习使用React一步步搭建普通博客应用
- xilinx 的hdmi core 接收端调试成功。