【树上莫队】bzoj3757 苹果树
学习这位神犇的:http://blog.csdn.net/jiangyuze831/article/details/41476865
注意:
①排序时第一关键字是左端点所在块编号(块状树),第二关键字是右端点dfs序。
②维护的当前链不能包括lca(l,r),但最后要计算上lca(l,r)的答案。
③对l->l'/r->r'取反的时候也不能取反lca(l,l')/lca(r,r')。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 50001
#define M 100001
int n,m;
int first[N],en,next[N<<1],dfsn[N],v[N<<1],fa[N],bel[N],dep[N],siz[N],cnt,top[N];
int x,y,root,sz,col[N],Time[N],ans,anss[M];
bool vis[N];
struct ASK{int l,r,a,b,id;void Read(){scanf("%d%d%d%d",&l,&r,&a,&b);}}Q[M];
bool operator < (const ASK &a,const ASK &b)
{return bel[a.l]!=bel[b.l] ? bel[a.l]<bel[b.l] : dfsn[a.r]<dfsn[b.r];}
void AddEdge(const int &U,const int &V)
{
v[++en]=V;
next[en]=first[U];
first[U]=en;
}
void dfs(int cur)
{
dfsn[cur]=++cnt;
for(int i=first[cur];i;i=next[i])
if(v[i]!=fa[cur])
{
dep[v[i]]=dep[cur]+1;
fa[v[i]]=cur;
dfs(v[i]);
}
}
void makeblock(int cur)
{
for(int i=first[cur];i;i=next[i])
if(v[i]!=fa[cur])
{
if(siz[bel[cur]]<sz)
{
++siz[bel[cur]];
bel[v[i]]=bel[cur];
top[v[i]]=top[cur];
}
makeblock(v[i]);
}
}
int QLCA(int U,int V)
{
while(U!=V)
{
if(top[U]==top[V])
{
if(dep[U]<dep[V])
swap(U,V);
U=fa[U];
}
else
{
if(dep[top[U]]<dep[top[V]])
swap(U,V);
U=fa[top[U]];
}
}
return U;
}
void update(const int &Col,const int &op)
{
Time[Col]+=op;
if(!Time[Col]) --ans;
else if(Time[Col]==1&&op==1) ++ans;
}
void Work(int U,int V,int lca)
{
while(U!=lca)
{
vis[U]^=1;
update(col[U],vis[U]?1:-1);
U=fa[U];
}
while(V!=lca)
{
vis[V]^=1;
update(col[V],vis[V]?1:-1);
V=fa[V];
}
}
void Solve(const int &p)
{
int lca=QLCA(Q[p].l,Q[p].r);
if(p==1) Work(Q[p].l,Q[p].r,lca);
else
{
Work(Q[p-1].l,Q[p].l,QLCA(Q[p-1].l,Q[p].l));
Work(Q[p-1].r,Q[p].r,QLCA(Q[p-1].r,Q[p].r));
}
update(col[lca],1);
anss[Q[p].id]=ans;
if(Q[p].a!=Q[p].b)
anss[Q[p].id]-=(Time[Q[p].a]&&Time[Q[p].b]);
update(col[lca],-1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&col[i]);
for(int i=1;i<=n;++i)
{
scanf("%d%d",&x,&y);
if(!x) root=y;
else if(!y) root=x;
else
{
AddEdge(x,y);
AddEdge(y,x);
}
}
dfs(root);
for(int i=1;i<=n;i++)
{
siz[bel[i]=dfsn[i]]=1;
top[i]=i;
}
sz=(((int)sqrt(n))<<1);
makeblock(root);
for(int i=1;i<=m;++i) Q[i].Read(),Q[i].id=i;
sort(Q+1,Q+m+1);
for(int i=1;i<=m;++i) Solve(i);
for(int i=1;i<=m;++i) printf("%d\n",anss[i]);
return 0;
}
【树上莫队】bzoj3757 苹果树的更多相关文章
- 【BZOJ-3757】苹果树 块状树 + 树上莫队
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1305 Solved: 503[Submit][Status][Discuss] ...
- [BZOJ3757]苹果树(树上莫队)
树上莫队共有三种写法: 1.按DFS序列分块,和普通莫队类似.常数大,不会被卡. 2.按块状树的方式分块.常数小,会被菊花图卡到O(n). 3.按[BZOJ1086]王室联邦的方式分块.常数小,不会被 ...
- BZOJ3757: 苹果树【树上莫队】
Description 神犇家门口种了一棵苹果树.苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条.由于这棵苹果树 ...
- 2018.09.16 bzoj3757: 苹果树(树上莫队)
传送门 一道树上莫队. 先用跟bzoj1086一样的方法给树分块. 分完之后就可以莫队了. 但是两个询问之间如何转移呢? 感觉很难受啊. 我们定义S(u,v)" role="pre ...
- 【BZOJ3757】苹果树(树上莫队)
点此看题面 大致题意: 每次问你树上两点之间路径中有多少种颜色,每次询问可能会将一种颜色\(a\)看成\(b\). 树上莫队 这题是一道树上莫队板子题. 毕竟求区间中有多少种不同的数是莫队算法的经典应 ...
- 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)
2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...
- 树上莫队 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 < ...
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
随机推荐
- 湖南大学第十四届ACM程序设计新生杯 E.Easy Problem
E.Easy Problem Description: Zghh likes number, but he doesn't like writing problem description. So h ...
- B. Light It Up 思维题
Recently, you bought a brand new smart lamp with programming features. At first, you set up a schedu ...
- egrep对于conf文件中去掉#注释,排除无用项
[root@localhost conf]# egrep -v "#|^$" nginx.conf.default > nginx.conf dd
- bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化
[Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 679 Solved: 534[Submit][S ...
- Struts2 利用拦截器 interceptor 控制登陆和访问权限
最近学习了Struts2的登录和权限控制用到的是拦截器,需要在struts.xml中配置,每个action都默认的继承defaultStack,如果你用了别的拦截器,还需要手动引入defaultSta ...
- MyBatis的SQL语句映射文件详解
SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用 < ...
- 转:Spring AOP 注解方式实现的一些“坑”
使用过Spring AOP的注解方式实现,也入过不少坑,现在做一下记录,希望有同样需求的朋友可以少走弯路 使用之前还是先过一下官方文档吧,至少可以少走弯路,不用担心英文读不懂,其实只看代码例子就能理解 ...
- php2go - Go 实现 PHP 常用内置函数
[转]http://www.syyong.com/Go/php2go-Use-Golang-to-implement-PHP-s-common-built-in-functions.html 使用Go ...
- bzoj4764: 弹飞大爷 link-cut-tree
题目传送门 这道题啊 调了一个晚上 因为写的是一个有根树和n个基环的写法 所以写得很奇怪..... 最后发现单独处理树的时候不能随意改变S(就是原来的根)不然size会出错.... #include& ...
- swift xcode设置 ,代码折叠,全局折叠 快捷键
在preference text editing 里面打开 function 折叠的项, 折叠方法快捷键: option+command +left/right 全局折叠快捷键: shift+opti ...