BZOJ 4285 使者 (CDQ分治+dfs序)
题目传送门
题目大意:给你一棵树,有三种操作,在两个点之间连一个传送门,拆毁一个已有的传送门,询问两个点之间的合法路径数量。一条合法路径满足 1.经过且仅经过一个传送门 2.不经过起点终点简单路径上的任何一条边
这模型转化好神啊
首先把树拍成$dfs$序
问题是在树上,我们把$x,y$这条链拎出来摊平,那么链上每个点都挂了一些子树。
容易发现合法路径数=连接以$x,y$为根的子树的传送门数量
而无根树并没有“子树”这一概念,所以先随便挑一个根跑出来dfs序。
发现“子树”的$dfs$序一定是一个或两个连续的区间,我们分$x,y$是否为$lca$讨论一下就可以了
然后把问题放到二维坐标系上。
问题转化成,动态在一个二维平面内加入/删除一个点,以及查询矩形内点的数量
由于存在修改操作,需要再加上一维。那么整个问题变成了一个三维偏序问题。用$CDQ$分治+树状数组即可
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 100005 6 #define M1 500005 7 #define ll long long 8 #define uint unsigned int 9 using namespace std; 10 11 template <typename _T> void read(_T &ret) 12 { 13 ret=0; _T fh=1; char c=getchar(); 14 while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); } 15 while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); } 16 ret=ret*fh; 17 } 18 19 struct Edge{ 20 int to[N1*2],nxt[N1*2],head[N1],cte; 21 void ae(int u,int v) 22 { cte++; to[cte]=v; nxt[cte]=head[u]; head[u]=cte; } 23 }e; 24 25 int n; 26 27 namespace Tree{ 28 int dep[N1],fa[N1],ff[N1][19],st[N1],ed[N1],ord[N1],cur; 29 void dfs1(int x) 30 { 31 int j,v; ff[x][0]=x; st[x]=++cur; ord[cur]=x;//sz[x]=1; 32 for(j=e.head[x];j;j=e.nxt[j]) 33 { 34 v=e.to[j]; if(v==fa[x]) continue; 35 fa[v]=x; ff[v][1]=x; dep[v]=dep[x]+1; 36 dfs1(v); 37 } 38 ed[x]=cur; 39 } 40 void init() 41 { 42 dep[1]=1; dfs1(1); 43 int i,j; 44 for(j=2;j<=18;j++) 45 for(i=1;i<=n;i++) 46 ff[i][j]=ff[ ff[i][j-1] ][j-1]; 47 } 48 int LCA(int x,int y) 49 { 50 int i,ans=0; 51 if(dep[x]<dep[y]) swap(x,y); 52 for(i=18;i>=0;i--) 53 if(dep[ff[x][i]]>=dep[y]) x=ff[x][i]; 54 if(x==y) return x; 55 for(i=18;i>=0;i--) 56 if(ff[x][i]==ff[y][i]) ans=ff[x][i]; 57 else x=ff[x][i], y=ff[y][i]; 58 return ans; 59 } 60 int LCB(int x,int D) 61 { 62 int i; 63 for(i=18;i>=0;i--) 64 if(dep[ff[x][i]]>=D) x=ff[x][i]; 65 return x; 66 } 67 }; 68 69 struct BIT{ 70 int sum[N1]; 71 void upd(int x,int w) 72 { 73 if(!x) return; int i; 74 for(i=x;i<=n;i+=(i&(-i))) 75 sum[i]+=w; 76 } 77 int query(int x) 78 { 79 int ans=0,i; 80 for(i=x;i>0;i-=(i&(-i))) 81 ans+=sum[i]; 82 return ans; 83 } 84 void clr(int x) 85 { 86 int i; 87 for(i=x;i<=n;i+=(i&(-i))) 88 sum[i]=0; 89 } 90 }bit; 91 92 struct OP{ int x,y,t,type,f; }op[M1],tmp[M1]; 93 int cmp2(OP &s1,OP &s2) 94 { 95 if(s1.x!=s2.x) return s1.x<s2.x; 96 if(s1.y!=s2.y) return s1.y<s2.y; 97 return s1.type<s2.type; 98 } 99 int ans[N1],que[M1],isquery[N1],tl; 100 101 void CDQ(int L,int R) 102 { 103 if(L==R) return; 104 int M=(L+R)>>1,i,j,cnt=0; 105 CDQ(L,M); CDQ(M+1,R); 106 for(i=L,j=M+1;i<=M&&j<=R;) 107 { 108 if(cmp2(op[i],op[j])){ 109 if(!op[i].type) bit.upd(op[i].y,op[i].f), que[++tl]=op[i].y; 110 tmp[++cnt]=op[i]; i++; 111 }else{ 112 if(op[j].type) ans[op[j].t]+=op[j].f*bit.query(op[j].y); 113 tmp[++cnt]=op[j]; j++; 114 } 115 } 116 while(i<=M){ tmp[++cnt]=op[i]; i++; } 117 while(j<=R){ tmp[++cnt]=op[j]; if(op[j].type) ans[op[j].t]+=op[j].f*bit.query(op[j].y); j++; } 118 for(i=L;i<=R;i++) op[i]=tmp[i-L+1]; 119 while(tl){ bit.clr(que[tl]); tl--; } 120 } 121 122 int m,Q1,Q2; 123 using Tree::st; using Tree::ed; using Tree::dep; using Tree::LCA; using Tree::LCB; 124 125 int main() 126 { 127 scanf("%d",&n); 128 int i,j,x,y,z,F,q,fl; 129 for(i=1;i<n;i++) read(x), read(y), e.ae(x,y), e.ae(y,x); 130 Tree::init(); 131 read(Q1); 132 for(q=1;q<=Q1;q++) 133 { 134 read(x); read(y); 135 op[++m]=(OP){st[x],st[y],0,0,1}; op[++m]=(OP){st[y],st[x],0,0,1}; 136 } 137 read(Q2); 138 for(q=1;q<=Q2;q++) { 139 140 read(fl); read(x); read(y); 141 if(fl==1){ 142 op[++m]=(OP){st[x],st[y],q,0,1}; op[++m]=(OP){st[y],st[x],q,0,1}; 143 }else if(fl==2){ 144 op[++m]=(OP){st[x],st[y],q,0,-1}; op[++m]=(OP){st[y],st[x],q,0,-1}; 145 }else if(fl==3){ 146 F=LCA(x,y); isquery[q]=1; 147 if(x==F||y==F){ 148 if(x==F) swap(x,y); z=LCB(x,dep[F]+1); 149 op[++m]=(OP){ed[x],st[z]-1,q,1,1}; //op[++m]=(OP){ed[x],0,q,1,-1}; 150 op[++m]=(OP){st[x]-1,st[z]-1,q,1,-1}; //op[++m]=(OP){st[x]-1,0,q,1,1}; 151 op[++m]=(OP){ed[x],n,q,1,1}; op[++m]=(OP){ed[x],ed[z],q,1,-1}; 152 op[++m]=(OP){st[x]-1,n,q,1,-1}; op[++m]=(OP){st[x]-1,ed[z],q,1,1}; 153 }else{ 154 op[++m]=(OP){ed[x],ed[y],q,1,1}; op[++m]=(OP){ed[x],st[y]-1,q,1,-1}; 155 op[++m]=(OP){st[x]-1,ed[y],q,1,-1}; op[++m]=(OP){st[x]-1,st[y]-1,q,1,1}; 156 } 157 } 158 159 } 160 161 CDQ(1,m); 162 for(i=1;i<=Q2;i++) if(isquery[i]) 163 printf("%d\n",ans[i]); 164 return 0; 165 }
转载于:https://www.cnblogs.com/guapisolo/p/10603729.html
BZOJ 4285 使者 (CDQ分治+dfs序)相关推荐
- 树链剖分 or 根号分治 + dfs序 + 树状数组 ---- CF1254 D. Tree Queries
题目链接 题目大意: 问题转化: 很容易发现:假设修改的节点是vvv. 1.vvv的子树sonvson_vsonv直接加上(n−size[sonv])n×d\frac{(n-size[son_v]) ...
- BZOJ 4043 [HAOI2015]树上操作 dfs序 线段树
$ \Rightarrow $ 戳我进BZOJ原题 $ \Rightarrow $ 戳我进洛谷原题 [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 25 ...
- bzoj 4237: 稻草人 cdq分治
求有多少个点对 其一个点为左下角 一个点为右下角所形成的矩形内部没有点 每个x与y都不同 一开始的思路: 先按照x坐标排序 进行cdq分治 然后在cdq内对y进行排序 枚举mid+1-r的点作 ...
- bzoj 1176 Mokia (cdq分治)
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MB Submit: 3874 Solved: 1742 [Submit] ...
- [bzoj] 1176 Mokia || CDQ分治
原题 给出W×W的矩阵(S没有用,题目有误),给出无限次操作,每次操作的含义为: 输入1:你需要把(x,y)(第x行第y列)的格子权值增加a 输入2:你需要求出以左下角为(x1,y1),右上角为(x2 ...
- BZOJ 3779 LCT 线段树 DFS序 坑
hhhh抄了半天lty代码最后T了 对拍也没事.. 药丸 mine #pragma GCC optimize("O3") //By SiriusRen #include < ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2221 Solved: 1179 [Submit][S ...
- bzoj 2141 : 排队 (cdq分治+bit)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141 思路: 其实就是求动态逆序对...cdq降维,用树状数组前后求两遍逆序对就好了 切水 ...
- cdq分治(bzoj 1176: [Balkan2007]Mokia bzoj 2683: 简单题)
CDQ分治: 本质:对询问进行分治 优点:和莫队分块一样都属于技巧,关键时刻能免去复杂的数据结构,常数小 缺点:必须离线 参考:http://blog.csdn.net/hbhcy98/article ...
最新文章
- UA MATH565C 随机微分方程V Markov Family的算子
- ajax html xml数据格式,AJAX | 数据格式JSON与XML的区别
- 客观地认识程序员心中的恐惧
- react native 包学不包会系列--认识react native
- 用 ABAP 读取本地文本文件内容试读版
- 如何从零开始,成为element-plus的contributor
- Java实现XSS防御
- 将字符转换成带有圆圈的字符
- mysql5.5.35编译安装_CentOS 6.5最小化编译安装mysql 5.5.35
- 给硬盘分个整数大小的区
- php调用API支付接口 可个人使用,无需营业执照(使用第三方接口,调用的天工接口。)...
- MacW编辑部的电脑都装了哪些苹果应用?
- cannot connect to 192.168.137.137:5555: 由于目标计算机积极拒绝,无法连接。
- UE4 后期处理 PostProcess
- 送你一份2023Java学习路线,按图索骥,开启一路狂飙!
- 《百年孤独》马尔克斯
- c语言溢出进位,Z80上的溢出和进位标志
- 张钹院士:场景是当前AI产业化最大问题
- android中有米广告报错java.lang.NoClassDefFoundError: net.youmi.android.AdManager
- 物理学在计算机中的物理应用题,「试题研究」中考物理综合应用题的特点
热门文章
- python求矩阵维度必须一致_python数据分析(二)--Numpy
- 事业编还是程序员_头条员工为不加班,降薪去事业单位,结果蒙了:还不如当程序员...
- java中数组的返回值是什么类型_java基础学习:数组的常用操作与基础二维数组用法、及基本数据类型和引用数据类型赋值的区别...
- Upload LABS Pass-9
- redis集群实现(六) 容灾与宕机恢复
- 启蒙英语仍在培育期,DaDaBaby缘何能裂变式增长?
- quidway secpath下搭建DHCP服务器01
- iphone 如何成功的把three20成功的添加到xcode中去。
- Java开发实战经典 目录
- python判断一个数是否是质数