BZOJ_3772_精神污染_主席树

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


orz popoqqq https://blog.csdn.net/popoqqq/article/details/43122821

写完之后发现有更简单的方法。。。

方法一:离线树状数组

首先有两种路径,1字形和V字形。

对于1字型的路径,包含它的路径两端一定在链顶的儿子的子树外和链底的子树内,在dfs序上就划出了两个线段。

对于V字形的路径,被它包含的路径两端一定在两个端点的子树内,这也是两个线段。

把每条路经的端点在dfs序中的位置看成二维平面上的点,然后离线树状数组二维数点即可。

方法二:出栈入栈序+主席树

把询问挂链(x,y),然后每个点维护根到这个点路径的信息。

在x这颗线段树上把y的入栈位置+1,出栈位置-1。

然后把询问分成x->lca,lca->y,每次分别查询x到y路径上dfn[lca]到dfn[x],dfn[lca]到dfn[y]之间的和,其中dfn[x]表示x在dfs序中的位置。

分析一下,对于其中包含的路径(z,w),z这个点一定在x到y路径上,故z刚刚做出的修改会在x到y这段路经上体现。

那么我们就只需要找w,由于我把入栈位置+1出栈位置-1,相当于差分实现区间加,因此查询时会查到w。

代码(方法二):

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100050
typedef long long ll;
int head[N],to[N<<1],nxt[N<<1],cnt,n,m,root[N],maxn;
int fa[N],top[N],siz[N],son[N],dep[N],dfn[N],S[N],out[N],t[N*39],tot,ls[N*39],rs[N*39];
inline void add(int u,int v) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void insert(int &y,int x,int l,int r,int v,int c) {
    y=++tot; t[y]=t[x]+c;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(v<=mid) rs[y]=rs[x],insert(ls[y],ls[x],l,mid,v,c);
    else ls[y]=ls[x],insert(rs[y],rs[x],mid+1,r,v,c);
}
int query(int a,int b,int c,int d,int l,int r,int x,int y) {
    if(x<=l&&y>=r) return t[a]+t[b]-t[c]-t[d];
    int mid=(l+r)>>1,re=0;
    if(x<=mid) re+=query(ls[a],ls[b],ls[c],ls[d],l,mid,x,y);
    if(y>mid) re+=query(rs[a],rs[b],rs[c],rs[d],mid+1,r,x,y);
    return re;
}
void dfs1(int x,int y) {
    S[++S[0]]=x; dfn[x]=++maxn;
    int i; dep[x]=dep[y]+1; fa[x]=y; siz[x]=1;
    for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
        dfs1(to[i],x); siz[x]+=siz[to[i]];
        if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
    }
    out[x]=++maxn;
}
void dfs2(int x,int t) {
    top[x]=t; int i; if(son[x]) dfs2(son[x],t);
    for(i=head[x];i;i=nxt[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
int lca(int x,int y) {
    while(top[x]!=top[y]) {
        if(dep[top[x]]>dep[top[y]]) swap(x,y);
        y=fa[top[y]];
    }
    return dep[x]<dep[y]?x:y;
}
ll gcd(ll x,ll y) {
    return y?gcd(y,x%y):x;
}
int main() {
    scanf("%d%d",&n,&m);
    int i,x,y,j;
    for(i=1;i<n;i++) {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    memset(head,0,sizeof(head)); cnt=0;
    for(i=1;i<=m;i++) {
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    for(j=1;j<=n;j++) {
        x=S[j];
        root[x]=root[fa[x]];
        for(i=head[x];i;i=nxt[i]) {
            y=to[i];
            insert(root[x],root[x],1,maxn,dfn[y],1);
            insert(root[x],root[x],1,maxn,out[y],-1);
        }
    }
    ll ans=0,dev=1ll*m*(m-1)/2;;
    for(x=1;x<=n;x++) {
        for(i=head[x];i;i=nxt[i]) {
            y=to[i];
            int l=lca(x,y);
            ans+=query(root[x],root[y],root[l],root[fa[l]],1,maxn,dfn[l],dfn[x]);
            ans+=query(root[x],root[y],root[l],root[fa[l]],1,maxn,dfn[l],dfn[y]);
            ans-=query(root[x],root[y],root[l],root[fa[l]],1,maxn,dfn[l],dfn[l]);
            ans--;
        }
    }
    ll tmp=gcd(ans,dev);
    printf("%lld/%lld\n",ans/tmp,dev/tmp);
}

原文地址:https://www.cnblogs.com/suika/p/8967726.html

时间: 2024-10-14 08:13:52

BZOJ_3772_精神污染_主席树的相关文章

BZOJ_4448_[Scoi2015]情报传递_主席树

Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈特公司纪律森严,每 名情报员只能与自己的上.下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报. 奈特公司每天会派发以下两种任务中的一个任务: 1.搜集情报:指派T号情报员搜集情报 2.传递情报:将一条情报从X号情报员传递给Y号情报员 情报员最初处于潜伏阶段,他们是相对安全的,我们

BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT

Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来M行,代表图中的每条边. 接下来K行,每行两个整数L.R代表一组询问.对于type=0的测试点,读入的L和R即为询问的L.R:对于type=1的测试点,每组询问的L.R应为L xor lastans和R xor lastans. Output K行每行一个整数代表该组询问的联通块个数. Sample

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

这道题的内存-------真·精神污染---.. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第一关键字,另一个作为第二关键字,于是就有了两维限制,按照主席树的一般思路,我们把建树顺序作为一维,然后在里面维护另一维,那么我们在外面限制第一关键字,就是在树上建主席树,查询减LCA,在里面的话我们把每个点作为第一关键字对应的第二关键字,放入主席树,而主席树维护的是欧拉序区间,所以我们每次查询只用查

bzoj 3772 精神污染 主席树+dfs序

精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 637  Solved: 177[Submit][Status][Discuss] Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海陆空交通设施发达.濑户内海沿岸气候温暖,多晴天,有日本少见的贸易良港神户港所在的神户市和曾是豪

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

3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 315  Solved: 87[Submit][Status][Discuss] Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海陆空交通设施发达.濑户内海沿岸气候温暖,多晴天,有日本少见的贸易良港神户港所在的神户

BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树

Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快!J要逆袭了!” …… 描述 这一天DJ在给吾等众蒟蒻讲题,花神在一边做题无聊,就跑到了一边跟吾等众蒟蒻一起听.以下是部分摘录: 1. “J你在讲什么!” “我在讲XXX!” “哎你傻不傻的!这么麻烦,直接XXX再XXX就好了!” “……” 2. “J你XXX讲过了没?” “……” “那个都不讲你就讲这个了?哎你傻不傻的!” “……”

Bzoj3772 精神污染

Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 446  Solved: 129 Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海陆空交通设施发达.濑户内海沿岸气候温暖,多晴天,有日本少见的贸易良港神户港所在的神户市和曾是豪族城邑“城下町”的姬路市等大城市,还有以疗养地而闻名的六甲山

主席树复习

T1 [CQOI2015]任务查询系统 n个任务,每个有运行的时间段和优先级,询问某一时刻,优先级最小的个任务的优先级之和 初做:  2017.2.4   http://www.cnblogs.com/TheRoadToTheGold/p/6366165.html 好像是做了一晚上来 现在:2017.3.27   14:17——15:56 用了接近2个小时做了一道以前做过的题,还是弱啊~~~~(>_<)~~~~ difference: 主席树维护的东西不同,以前直接存储优先级之和,现在存储的是

BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LC