精神污染

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 637  Solved: 177
[Submit][Status][Discuss]

Description

兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海陆空交通设施发达。濑户内海沿岸气候温暖,多晴天,有日本少见的贸易良港神户港所在的神户市和曾是豪族城邑“城下町”的姬路市等大城市,还有以疗养地而闻名的六甲山地等。
兵库县官方也大力发展旅游,为了方便,他们在县内的N个旅游景点上建立了n-1条观光道,构成了一棵图论中的树。同时他们推出了M条观光线路,每条线路由两个节点x和y指定,经过的旅游景点就是树上x到y的唯一路径上的点。保证一条路径只出现一次。
你和你的朋友打算前往兵库县旅游,但旅行社还没有告知你们最终选择的观光线路是哪一条(假设是线路A)。这时候你得到了一个消息:在兵库北有一群丧心病狂的香菜蜜,他们已经选定了一条观光线路(假设是线路B),对这条路线上的所有景点都释放了【精神污染】。这个计划还有可能影响其他的线路,比如有四个景点1-2-3-4,而【精神污染】的路径是1-4,那么1-3,2-4,1-2等路径也被视为被完全污染了。
现在你想知道的是,假设随便选择两条不同的路径A和B,存在一条路径使得如果这条路径被污染,另一条路径也被污染的概率。换句话说,一条路径被另一条路径包含的概率。
 

Input

第一行两个整数N,M
接下来N-1行,每行两个数a,b,表示A和B之间有一条观光道。
接下来M行,每行两个数x,y,表示一条旅游线路。
 

Output

所求的概率,以最简分数形式输出。
 

Sample Input

5 3
1 2
2 3
3 4
2 5
3 5
2 5
1 4

Sample Output

1/3
样例解释
可以选择的路径对有(1,2),(1,3),(2,3),只有路径1完全覆盖路径2。

HINT

100%的数据满足:N,M<=100000
 
题解:
  将每个询问的点,按照dfs序的顺序,建立主席树
  每棵线段树的版本是其祖先的版本加上询问中在其节点上的,
  比如询问是x,y,那么建树在建到x的时候,将y加入当前线段树
  在y的in中加1,out中减1,in表示进入的dfs序,out表示出来的dfs序
  这个有什么用呢。
  
  对于询问x,y,f表示其lca,就是询问x和y的树中
  

  比如统计两个红点的答案,分别为x,y,f为lca,

  所以答案+x,y,f,fa[f]上询问in[f],in[x]

      +x,y,f,fa[f]上询问in[f],in[y]

      -x,y,f,fa[f]上询问in[f],in[f]

      -1减去自己

  即可。

  题目给的是没有相同的路径的。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<algorithm>
#include<cmath> #define ll long long
#define N 100007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch>''||ch<''){if (ch=='-') f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,ind,sz;
ll fz,fm;
int ls[N*],rs[N*],sum[N*];
int deep[N],root[N*],in[N],out[N];
int fa[N][],ci[];
vector<int>a[N];
int cnt,hed[N],nxt[N*],rea[N*];
struct query
{
int x,y;
}q[N];
bool operator<(query a,query b)
{
if(a.x==b.x)return a.y<b.y;
else return a.x<b.x;
} ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
void add(int u,int v)
{
nxt[++cnt]=hed[u];
hed[u]=cnt;
rea[cnt]=v;
}
void dfs(int x)
{
for(int i=;(<<i)<=deep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
in[x]=++ind;
for(int i=hed[x];i!=-;i=nxt[i])
{
int v=rea[i];
if(v!=fa[x][])
{
fa[v][]=x;
deep[v]=deep[x]+;
dfs(v);
}
}
out[x]=++ind;
}
inline void update(int p){sum[p]=sum[ls[p]]+sum[rs[p]];}
/*void ins(int yl,int &xz,int l,int r,int pos,int val)
{
xz=++sz,ls[xz]=ls[yl],rs[xz]=rs[yl];
if(l==r)
{
sum[xz]=sum[yl]+val;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) ins(ls[yl],ls[xz],l,mid,pos,val);
else ins(rs[yl],rs[xz],mid+1,r,pos,val);
update(xz);
}*/ int insert(int x,int l,int r,int pos,int val)
{
int t=++sz;
ls[t]=ls[x];rs[t]=rs[x];
if(l==r){sum[t]=sum[x]+val;return t;}
int mid=(l+r)>>;
if(pos<=mid)ls[t]=insert(ls[t],l,mid,pos,val);
else rs[t]=insert(rs[t],mid+,r,pos,val);
sum[t]=sum[ls[t]]+sum[rs[t]];
return t;
}
int query(int p1,int p2,int p3,int p4,int l,int r,int st,int ed)
{
int mid=(l+r)>>;
if(l==st&&r==ed) {return sum[p1]+sum[p2]-sum[p3]-sum[p4];}
if(ed<=mid) return query(ls[p1],ls[p2],ls[p3],ls[p4],l,mid,st,ed);
else if(st>mid) return query(rs[p1],rs[p2],rs[p3],rs[p4],mid+,r,st,ed);
else return query(ls[p1],ls[p2],ls[p3],ls[p4],l,mid,st,mid)+query(rs[p1],rs[p2],rs[p3],rs[p4],mid+,r,mid+,ed);
}
/*
void build(int x)
{
root[0]=root[fa[x][0]];
for(int i=0;i<a[x].size();i++)
{
ins(root[0],root[N-1],1,ind,in[a[x][i]],1);
ins(root[N-1],root[x],1,ind,out[a[x][i]],-1);
}
for(int i=hed[x];i!=-1;i=nxt[i])
{
int v=rea[i];
if(v!=fa[x][0]) build(v);
}
}*/ void build(int x)
{
root[x]=root[fa[x][]];
for(int i=;i<a[x].size();i++)
{
root[x]=insert(root[x],,ind,in[a[x][i]],);
root[x]=insert(root[x],,ind,out[a[x][i]],-);
}
for(int i=hed[x];i!=-;i=nxt[i])
{
int v=rea[i];
if(v!=fa[x][])
build(v);
}
}
int lca(int a,int b)
{
if (deep[a]<deep[b]) swap(a,b);
int i;for (i=;(<<i)<=deep[a];i++);i--;
for (int j=i;j>=;j--)
if (deep[a]-(<<j)>=deep[b]) a=fa[a][j];
if (a==b) return a;
for (int j=i;j>=;j--)
if (fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j];
return fa[a][];
}
void solve()
{
for(int i=;i<=m;i++)
{
int x=q[i].x,y=q[i].y,f=lca(x,y);
fz+=query(root[x],root[y],root[f],root[fa[f][]],,ind,in[f],in[x]);
fz+=query(root[x],root[y],root[f],root[fa[f][]],,ind,in[f],in[y]);
fz-=query(root[x],root[y],root[f],root[fa[f][]],,ind,in[f],in[f]);
fz--;
}
}
inline void init()
{
ci[]=;
for(int i=;i<;i++)ci[i]=ci[i-]<<; memset(hed,-,sizeof(hed));
n=read();m=read();
for(int i=;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);//加边,没什么问题。
}
for(int i=;i<=m;i++)
{
int x=read(),y=read();
a[x].push_back(y);//在边的起点放入另外一个端点。
q[i].x=x,q[i].y=y;
}
sort(q+,q+m+);//q按照x为第一关键字来排序。
}
int main()
{
freopen("fzy.in","r",stdin);
freopen("fzy.out","w",stdout); init(),dfs(),build(),solve(); fm=(ll)m*(m-)/;
ll t=gcd(fz,fm);
fz/=t;fm/=t;
printf("%lld/%lld",fz,fm);
}

bzoj 3772 精神污染 主席树+dfs序的更多相关文章

  1. BZOJ3772 精神污染 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3772 题意概括 给出一个树,共n个节点. 有m条互不相同的树上路径. 现在让你随机选择2条路径,问 ...

  2. bzoj 3772 :精神污染 线段树+打标记 or 主席树

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 315  Solved: 87[Submit][Status][Discuss] D ...

  3. BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...

  4. 51 nod 1681 公共祖先 (主席树+dfs序)

    1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...

  5. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

  6. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

  7. BZOJ 3772: 精神污染(dfs序+主席树)

    传送门 解题思路 比较神仙的一道题.首先计算答案时可以每条路径所包含的路径数,对于\(x,y\)这条路径,可以在\(x\)这处开个\(vector\)存\(y\),然后计算时只需要算这个路径上每个点的 ...

  8. 【BZOJ 3772】精神污染 主席树+欧拉序

    这道题的内存…………………真·精神污染……….. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第 ...

  9. BZOJ3772 精神污染 【主席树 + dfs序】

    题目 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海 ...

随机推荐

  1. 动手实现 Redux(三):纯函数(Pure Function)简介

    我们接下来会继续优化我们的 createStore 的模式,让它使我们的应用程序获得更好的性能. 但在开始之前,我们先用一节的课程来介绍一下一个函数式编程里面非常重要的概念 —— 纯函数(Pure F ...

  2. JavaScript——数组的indexOf()方法在IE8中的兼容性问题

    昨天在工作中遇到一个问题:数组的indexOf()方法在IE8中无效. 如以下代码在IE8中报错“对象不支持“indexOf”属性或方法”: var arr = [1,2,3]; var index ...

  3. git找不到远程库问题

    git报错:Couldn't find remote ref XXXX (gitlab报错)XXXX does not appear to be a git repository Could not ...

  4. 探究SQL添加非聚集索引,性能提高几十倍之谜

    上周,技术支持反映:客户的一个查询操作需要耗时6.1min左右,在跟进代码后,简化了数据库的查询后仍然收效甚微.后来,技术总监分析了sql后,给其中的一个表添加的一个非聚集索引(三个字段)后,同样的查 ...

  5. android studio 导入jar包

    或者还可以这么导入: 1.首先先去下载需要的jar包2.将jar包复制到Project下的app–>libs目录下(没有libs目录就新建一个)如下图所示位置: 3.点击工具栏中的Project ...

  6. Javaweb学习笔记7—JDBC技术

      今天来讲javaweb的第7阶段学习. JDBC技术,关于JDBC本篇博客只介绍了它的一部分,后面博客会更加深入探讨. 老规矩,首先先用一张思维导图来展现今天的博客内容.   ps:我的思维是用的 ...

  7. 事件绑定、取消的二种形式 & call

    <script> //call 函数下的一个方法,call方法第一个参数可以改变函数执行过程中的内部this的指向,call方法第二个参数开始就是原来函数的参数列表. function f ...

  8. example - 在这里插入一句话的简介

    总览 (SYNOPSIS) example [options] arguments 描述 (DESCRIPTION) 在这里插入描述 man9 应当是 “内核文档” 但是由于内核文档一般不以 man ...

  9. uva1610 Party Games

    细节值得注意 注意vector<string>是可以直接sort的! #include <iostream> #include <string> #include ...

  10. Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use ...报错

    错误截图 Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* t ...