[BZOJ 3772]精神污染 主席树+dfs序
来源:互联网 发布:端口号80是什么意思 编辑:程序博客网 时间:2024/05/21 11:20
这题目描述是真...精神污染..
比较有趣的一道题目,首先显然ans=所有两两之间有包含关系的路径/所有的方案数
那么,现在问题就变成了如何快速的找到有包含关系的路径.
假设现在有路径A以及路径B,切A包含于B,那么显然A的两个端点都在B这条路径上,也就是说我们只需要找到所有起点和终点都在B路径上面的路径.这里由于路径很难维护,所有就维护当前节点到根节点的信息.
主席树维护dfs序(每一个点都有入栈和出栈不同的编号)
这里主席树维护的信息是:对于每一个节点的树是以这个节点为起点的终点区间和,所以整个主席树就是以这个节点到根节点之间的这一部分节点为起点的终点.而且入栈为1,出栈为-1,这样只用查询in[rt]->in[u]就是跟到节点之间的信息,其他的+1和-1相互抵消
剩下的随便++--就好了
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#define LL long long#define maxn 100005using namespace std;vector<int>g[maxn];LL A,B;int head[maxn],tot=1,in[maxn],out[maxn],sz,h[maxn],cnt,rt[maxn];int f[maxn][17],sum[maxn*38],rs[maxn*38],ls[maxn*38],n,m;struct que{int x,y;}q[maxn];struct edge{int v,next;}e[maxn*2];void adde(int a,int b){e[tot].v=b,e[tot].next=head[a];head[a]=tot++;}LL gcd(LL a,LL b){return !b ? a : gcd(b,a%b);}void insert(int x,int& y,int l,int r,int id,int add){y=++cnt;ls[y]=ls[x],rs[y]=rs[x],sum[y]=sum[x]+add;if(l==r)return;int mid=l+r>>1;if(id>mid)insert(rs[x],rs[y],mid+1,r,id,add);else insert(ls[x],ls[y],l,mid,id,add);}int query(int x,int a,int y,int b,int l,int r,int s,int t){if(s==l&&t==r)return sum[x]+sum[a]-sum[b]-sum[y];int mid=l+r>>1;if(s>mid)return query(rs[x],rs[a],rs[y],rs[b],mid+1,r,s,t);else if(t<=mid)return query(ls[x],ls[a],ls[y],ls[b],l,mid,s,t);else return query(rs[x],rs[a],rs[y],rs[b],mid+1,r,mid+1,t)+ query(ls[x],ls[a],ls[y],ls[b],l,mid,s,mid);}void dfs1(int u,int fa){f[u][0]=fa,h[u]=h[fa]+1;in[u]=++sz;for(int i=1;i<=16;i++)f[u][i]=f[f[u][i-1]][i-1];for(int v,i=head[u];i;i=e[i].next){if((v=e[i].v)==fa)continue;dfs1(v,u);}out[u]=++sz;}void dfs2(int u,int fa){rt[u]=rt[fa];for(int i=0;i<g[u].size();i++){insert(rt[u],rt[u],1,sz,in[g[u][i]],1);insert(rt[u],rt[u],1,sz,out[g[u][i]],-1);}for(int v,i=head[u];i;i=e[i].next){if((v=e[i].v)==fa)continue;dfs2(v,u);}}int lca(int a,int b){if(h[a]>h[b])swap(a,b);for(int i=16;i>=0;i--)if(h[f[b][i]]>=h[a])b=f[b][i];if(a==b)return a;for(int i=16;i>=0;i--){if(f[a][i]==f[b][i])continue;a=f[a][i],b=f[b][i];}return f[a][0];}void solve(){int a,b,g,fg;for(int i=1;i<=m;i++){a=q[i].x,b=q[i].y,g=lca(a,b),fg=f[g][0];A--;A+=query(rt[a],rt[b],rt[g],rt[fg],1,sz,in[g],in[a]);A+=query(rt[a],rt[b],rt[g],rt[fg],1,sz,in[g],in[b]);A-=query(rt[a],rt[b],rt[g],rt[fg],1,sz,in[g],in[g]);}}int main(){scanf("%d%d",&n,&m);for(int a,b,i=1;i<n;i++){scanf("%d%d",&a,&b);adde(a,b),adde(b,a);}for(int a,b,i=1;i<=m;i++){scanf("%d%d",&a,&b);g[a].push_back(b);q[i]=(que){a,b};}dfs1(1,0);dfs2(1,0);solve();B=(LL)m*(m-1)/2;LL t=gcd(A,B);A/=t,B/=t;printf("%lld/%lld",A,B);return 0;}
0 0
- bzoj 3772: 精神污染 (主席树+dfs序)
- [BZOJ 3772]精神污染 主席树+dfs序
- 【bzoj3772】 精神污染 dfs序+主席树
- BZOJ 3772 精神污染 主席树+欧拉序
- [BZOJ3772]精神污染(dfs序+主席树)
- [BZOJ3772]精神污染(主席树+链剖)
- [BZOJ3772]精神污染(主席树)
- BZOJ 3772 精神污染 可持久化线段树
- bzoj 1803(主席树+dfs序)
- bzoj 1803(DFS序+主席树)
- BZOJ 4756 主席树+dfs
- bzoj 3653: 谈笑风生 (主席树+dfs序)
- bzoj 3551 kruskal重构树dfs序上的主席树
- BZOJ 4756 [Usaco2017 Jan]Promotion Counting dfs序+主席树
- [BZOJ Contest-2017省队十连测推广赛2·T2][BZOJ4771][主席树][dfs序]七彩树
- [BZOJ 2588][SPOJ COT]Count On a Tree(DFS序主席树)
- [省选前题目整理][BZOJ 2588][SPOJ COT]Count On a Tree(DFS序主席树)
- spoj Query on a tree3/bzoj 1803(DFS序+主席树)
- H5项目常见问题汇总及解决方案
- sql server 安装
- Java 性能优化系列之3.1[JVM调优]
- 火狐下f5刷新页面缓存hidden的值的解决办法
- 九度OJ-1054:字符串内排序
- [BZOJ 3772]精神污染 主席树+dfs序
- Struts2(四) 页面相关内容
- js创建对象(推荐)
- 产出文件乱码问题
- Leetcode #530 Minimum Absolute Difference in BST
- 提高php运行效率的50个技巧
- 请将标为Service Pack 2 CD-ROM的光盘插入CD-ROM驱动器(D:),然后单击确定。如何解决? 在windows server 2003服务器上。
- 电视应用接入微信登录的那些坑
- css截取超出的文本+label标签的‘for’属性