[BZOJ3757]苹果树(树上莫队)
树上莫队共有三种写法:
1.按DFS序列分块,和普通莫队类似。常数大,不会被卡。
2.按块状树的方式分块。常数小,会被菊花图卡到O(n)。
3.按[BZOJ1086]王室联邦的方式分块。常数小,不会被卡。唯一的缺点是较抽象,一个块可能是不连通的。
权衡一下当然还是写第三种做法,具体看代码。
然后还有一个问题,手动模拟莫队移动左右端点指针的过程,会发现LCA处较难处理,它常常是跟其它点反着的。于是我们每次移指针的时候都忽略LCA,最后询问的时候加上LCA求解答案再减去LCA。再模拟会发现,所有方案都可以处理了。
以及要注意每个询问如果左端点所在块编号比右端点所在块大则需要交换左右端点。询问的排序方式是:若两端点不在同一块则按块编号排序,否则按DFS序排序。也就是按(bel[i],dfn[i])的双关键字排序。
#include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=;
int n,m,B,u,v,tim,top,tot,a[N],stk[N],b[N],dep[N],fa[N][];
int cnt,res,rt,vis[N],ans[N],dfn[N],s[N],h[N],to[N],nxt[N];
struct P{ int l,r,x,y,id; }q[N]; bool cmp(const P &x,const P &y){ return b[x.l]==b[y.l] ? dfn[x.r]<dfn[y.r] : b[x.l]<b[y.l]; }
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } void dfs(int x){
dfn[x]=++tim; int tmp=top;
rep(i,,) fa[x][i]=fa[fa[x][i-]][i-];
For(i,x) if ((k=to[i])!=fa[x][]){
fa[k][]=x; dep[k]=dep[x]+; dfs(k);
if (top-tmp>=B){ ++tot; while (top!=tmp) b[stk[top--]]=tot; }
}
stk[++top]=x;
} int lca(int x,int y){
if (dep[x]<dep[y]) swap(x,y);
int t=dep[x]-dep[y];
for (int i=; ~i; i--) if (t&(<<i)) x=fa[x][i];
if (x==y) return x;
for (int i=; ~i; i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
} void upd(int x){
if (vis[x]){ s[a[x]]--; if (!s[a[x]]) res--; }
else { s[a[x]]++; if (s[a[x]]==) res++; }
vis[x]^=;
} void work(int x,int y){
for (; x!=y; upd(x),x=fa[x][])
if (dep[x]<dep[y]) swap(x,y);
} int main(){
freopen("bzoj3757.in","r",stdin);
freopen("bzoj3757.out","w",stdout);
scanf("%d%d",&n,&m); B=sqrt(n);
rep(i,,n) scanf("%d",&a[i]);
rep(i,,n){
scanf("%d%d",&u,&v);
if (!u || !v) { rt=u+v; continue; }
add(u,v); add(v,u);
}
dfs(rt);
while (top) b[stk[top--]]=tot;
rep(i,,m){
scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].x,&q[i].y); q[i].id=i;
if (b[q[i].l]>b[q[i].r]) swap(q[i].l,q[i].r);
}
sort(q+,q+m+,cmp);
int L=rt,R=rt;
rep(i,,m){
work(L,q[i].l); work(R,q[i].r); L=q[i].l; R=q[i].r;
int f=lca(L,R); upd(f);
ans[q[i].id]=res-(int)(q[i].x!=q[i].y&&s[q[i].x]&&s[q[i].y]); upd(f);
}
rep(i,,m) printf("%d\n",ans[i]);
return ;
}
[BZOJ3757]苹果树(树上莫队)的更多相关文章
- 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)
2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...
- BZOJ.3757.苹果树(树上莫队)
题面链接 /* 代码正确性不保证..(不过交了SPOJ没WA T了最后一个点) 在DFS序做莫队 当一个点不是另一个点的LCA时,需要加上它们LCA的贡献 */ #include <cmath& ...
- 【BZOJ-3757】苹果树 块状树 + 树上莫队
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1305 Solved: 503[Submit][Status][Discuss] ...
- BZOJ3757: 苹果树【树上莫队】
Description 神犇家门口种了一棵苹果树.苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条.由于这棵苹果树 ...
- 2018.09.16 bzoj3757: 苹果树(树上莫队)
传送门 一道树上莫队. 先用跟bzoj1086一样的方法给树分块. 分完之后就可以莫队了. 但是两个询问之间如何转移呢? 感觉很难受啊. 我们定义S(u,v)" role="pre ...
- 【BZOJ3757】苹果树(树上莫队)
点此看题面 大致题意: 每次问你树上两点之间路径中有多少种颜色,每次询问可能会将一种颜色\(a\)看成\(b\). 树上莫队 这题是一道树上莫队板子题. 毕竟求区间中有多少种不同的数是莫队算法的经典应 ...
- 树上莫队 wowow
构建:像线性的莫队那样,依旧是按sqrt(n)为一块分块. int dfs(int x){ ; dfn[x]=++ind; ;i<=;i++) if (bin[i]<=deep[x]) f ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
随机推荐
- 鸟哥的Linux私房菜——第十九章:例行命令的建立
视频链接:http://www.bilibili.com/video/av11008859/ 1. 什么是例行性命令 (分为两种,一种是周期性的,一种是突发性的)1.1 Linux 工作排程的种类: ...
- 项目中经常用到的JavaScript方法
1. js切割字符串 String.split() 注意:此方法与Array.join执行的方法是相反的. 2. js把数组中所有元素放入一个字符串 Array.join()
- bzoj千题计划293:bzoj3142: [Hnoi2013]数列
http://www.lydsy.com/JudgeOnline/problem.php?id=3142 如果已知数列的差分数列a[1]~a[k-1] 那么这种差分方式对答案的贡献为 N-Σ a[i] ...
- Codeforces 923 D. Picking Strings
http://codeforces.com/contest/923/problem/D 题意: A-->BC , B-->AC , C-->AB , AAA-->empty 问 ...
- Struts2_day02
一.内容大纲 1 结果页面配置 (1)全局结果页面 (2)局部结果页面 - 配置全局也配置局部,最终局部为准 (3)result标签type属性 - 默认值 dispatcher做转发 - redir ...
- CSS规范 - 代码格式--(来自网易)
选择器.属性和值都使用小写 在xhtml标准中规定了所有标签.属性和值都小写,CSS也是如此.单行写完一个选择器定义 便于选择器的寻找和阅读,也便于插入新选择器和编辑,便于模块等的识别.去除多余空格, ...
- 2016最新的中国省市区三级数据库表.sql mssql
/****** Object: Table [dbo].[t_Area] Script Date: 09/10/2016 09:35:46 ******/ SET ANSI_NULLS ON GO S ...
- linux笔记_day10_shell编程
1.shell编程 编程语言 静态语言:编译型语言 强类型(变量在使用前,必须事先声明) 事先转换成可执行语言 动态语言:解释型语言 弱类型(变量用时声明,拿来直接用,甚至不区分数据类型,一般默认都为 ...
- 恶意代码分析实战-PE资源提取
场景 1.提取恶意代码中的资源部分内容 思路 存在Loadresource函数的时候说明有一部分内容在资源里. 技术点 Lab1-4 ResourceHacker打开保存资源,载入IDA查看
- CasperJS API中文博客链接
http://www.cnblogs.com/reach296/tag/Casperjs/