传送门

解题思路

  比较神仙的一道题。首先计算答案时可以每条路径所包含的路径数,对于\(x,y\)这条路径,可以在\(x\)这处开个\(vector\)存\(y\),然后计算时只需要算这个路径上每个点的\(vector\)中的元素是否也在这条路径上。这个可以用主席树维护,主席树维护括号序列,进时\(+1\),出时\(-1\),然后加加减减算一下。这题卡空间。。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=100005;
  4. const int M=N*38;
  5. typedef long long LL;
  6. inline int rd(){
  7. int x=0,f=1; char ch=getchar();
  8. while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
  9. while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
  10. return f?x:-x;
  11. }
  12. int n,m,head[N],cnt,to[N<<1],nxt[N<<1],xx[N],yy[N],siz[N],son[N];
  13. int rt[N<<1],fa[N],top[N],in[N],num,out[N],tot,dep[N];
  14. LL ans,sum;
  15. vector<int> v[N];
  16. struct Segment_Tree{
  17. int ls[M],rs[M],sum[M];
  18. void build(int &x,int l,int r){
  19. x=++tot; if(l==r) return ;
  20. int mid=(l+r)>>1;
  21. build(ls[x],l,mid); build(rs[x],mid+1,r);
  22. }
  23. int update(int pre,int l,int r,int pos,int k){
  24. int now=++tot,mid=(l+r)>>1;
  25. if(l==r) {sum[now]=sum[pre]+k; return now;}
  26. if(pos<=mid) rs[now]=rs[pre],ls[now]=update(ls[pre],l,mid,pos,k);
  27. else ls[now]=ls[pre],rs[now]=update(rs[pre],mid+1,r,pos,k);
  28. sum[now]=sum[ls[now]]+sum[rs[now]];
  29. return now;
  30. }
  31. int query(int x,int y,int lca,int F,int l,int r,int L,int R){
  32. if(L>R) return 0;
  33. if(L==l && r==R) return sum[x]+sum[y]-sum[lca]-sum[F];
  34. int mid=(l+r)>>1;
  35. if(R<=mid) return query(ls[x],ls[y],ls[lca],ls[F],l,mid,L,R);
  36. else if(L>mid) return query(rs[x],rs[y],rs[lca],rs[F],mid+1,r,L,R);
  37. else return query(ls[x],ls[y],ls[lca],ls[F],l,mid,L,mid)+query(rs[x],rs[y],rs[lca],rs[F],mid+1,r,mid+1,R);
  38. }
  39. int ask(int x,int l,int r,int L,int R){
  40. if(L<=l && r<=R) return sum[x];
  41. int mid=(l+r)>>1,ret=0;
  42. if(L<=mid) ret+=ask(ls[x],l,mid,L,R);
  43. if(mid<R) ret+=ask(rs[x],mid+1,r,L,R);
  44. return ret;
  45. }
  46. }tree;
  47. inline void add(int bg,int ed){
  48. to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
  49. }
  50. void dfs(int x,int F){
  51. in[x]=++num; fa[x]=F; siz[x]=1; int maxson=-1;
  52. for(int i=head[x];i;i=nxt[i]){
  53. int u=to[i]; if(u==F) continue;
  54. dep[u]=dep[x]+1; dfs(u,x);
  55. siz[x]+=siz[u];
  56. if(siz[u]>maxson) maxson=siz[u],son[x]=u;
  57. }
  58. out[x]=++num;
  59. }
  60. void dfs2(int x,int F){
  61. rt[x]=rt[F];
  62. for(int i=0;i<v[x].size();i++) {
  63. rt[x]=tree.update(rt[x],1,2*n,in[v[x][i]],1);
  64. rt[x]=tree.update(rt[x],1,2*n,out[v[x][i]],-1);
  65. }
  66. for(int i=head[x];i;i=nxt[i]){
  67. int u=to[i]; if(u==F) continue;
  68. dfs2(u,x);
  69. }
  70. }
  71. void dfs3(int x,int topf){
  72. top[x]=topf; if(!son[x]) return;
  73. dfs3(son[x],topf);
  74. for(int i=head[x];i;i=nxt[i]){
  75. int u=to[i]; if(u==fa[x] || u==son[x]) continue;
  76. dfs3(u,u);
  77. }
  78. }
  79. inline int LCA(int x,int y){
  80. while(top[x]!=top[y]){
  81. if(dep[top[x]]>=dep[top[y]]) x=fa[top[x]];
  82. else y=fa[top[y]];
  83. }
  84. return dep[x]>dep[y]?y:x;
  85. }
  86. int main(){
  87. n=rd(),m=rd(); int x,y,lca;
  88. for(register int i=1;i<n;i++){
  89. x=rd(),y=rd();
  90. add(x,y),add(y,x);
  91. }
  92. for(register int i=1;i<=m;i++){
  93. x=rd(),y=rd();
  94. xx[i]=x,yy[i]=y;
  95. v[x].push_back(y);
  96. } dep[1]=1;
  97. dfs(1,0); dfs2(1,0); dfs3(1,1);
  98. for(register int i=1;i<=m;i++){
  99. x=xx[i],y=yy[i],lca=LCA(x,y);
  100. ans+=tree.query(rt[x],rt[y],rt[lca],rt[fa[lca]],1,2*n,in[lca],in[x]);
  101. ans+=tree.query(rt[x],rt[y],rt[lca],rt[fa[lca]],1,2*n,in[lca],in[y]);
  102. ans-=tree.query(rt[x],rt[y],rt[lca],rt[fa[lca]],1,2*n,in[lca],in[lca]);
  103. ans--;
  104. }
  105. sum=(LL)m*(m-1)/2; LL GCD=__gcd(ans,sum);
  106. printf("%lld/%lld\n",ans/GCD,sum/GCD);
  107. return 0;
  108. }

BZOJ 3772: 精神污染(dfs序+主席树)的更多相关文章

  1. 【BZOJ3772】精神污染 DFS序+主席树

    [BZOJ3772]精神污染 Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是 ...

  2. bzoj3772 精神污染 dfs 序+主席树

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3772 题解 很简单的一道题目. 上午研究一个题目的时候发现了这个题目是一个弱化版,所以来写了一 ...

  3. BZOJ 3772: 精神污染 (dfs序+树状数组)

    跟 BZOJ 4009: [HNOI2015]接水果一样- CODE #include <set> #include <queue> #include <cctype&g ...

  4. bzoj 3653: 谈笑风生【dfs序+主席树】

    考虑b的两种情况,一种是p的祖先,这种点有min(k,de[p]-1)个,然后每个这种b都有si[p]-1个c点可选: 另一种是p的子孙,要求是在p的子树内且deep在de[p]+1~de[p]+k之 ...

  5. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  6. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  7. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

    bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...

  8. 【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树

    题目描述 You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node w ...

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

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

随机推荐

  1. vue事件的绑定

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Vue混入:全局混入

    一 项目结构 二 main.js import Vue from "vue"; import App from "./App.vue"; Vue.config. ...

  3. python实现获取文件夹中的最新文件

    实现代码如下: #查找某目录中的最新文件import osclass FindNewFile: def find_NewFile(self,path): #获取文件夹中的所有文件 lists = os ...

  4. c语言自带的排序与查找

    qsort与bsearch qsort(元素起始地址,元素总数,单个元素的大小,比较函数) bsearch(key元素地址,元素起始地址,元素总数,单个元素的大小,比较函数) 比较函数: 原型为int ...

  5. Vue CLI UI:Vue开发者必不可少的工具

    突然发现一个Vue cli 比较好用的工具,一个可视化图形界面方便你去创建.更新和管理Vue项目.这里分享2个作者写得比较好的文章 https://codeseeding.com/portal.php ...

  6. UI自动化处理文件上传

    UI自动化处理文件上传 import win32guiimport win32con def set_uploader(self, file_path): sleep(2) self.file_pat ...

  7. flex布局解说和属性

    1. flex-direction 规定当前DIV下面的子元素是横向布局还是纵向布局 row 默认值,横向布局相当于float:left column 纵向,相当于DIV默认的垂直方向 2.justi ...

  8. Pandas案例--人口密度分析

    需求: 导入文件,查看原始数据 将人口数据和各州简称数据进行合并 将合并的数据中重复的abbreviation列进行删除 查看存在缺失数据的列 找到有哪些state/region使得state的值为N ...

  9. 验证客户端的合法性、socketserver模块

    一.为了防止客户端被人非法利用,需要在使用之前对客户端进行合法性验证.接下来就是客户端验证的几种方法 hmac  加密方法 import socket import os import hmac #能 ...

  10. python 列表总结大全

    1定义 names=[] names=[1,2,1,1,1,] names=[1.'10'.[1,1]] 2添加元素 names.append() names.insert(0,10) names.e ...