学习这位神犇的: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 苹果树的更多相关文章

  1. 【BZOJ-3757】苹果树 块状树 + 树上莫队

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1305  Solved: 503[Submit][Status][Discuss] ...

  2. [BZOJ3757]苹果树(树上莫队)

    树上莫队共有三种写法: 1.按DFS序列分块,和普通莫队类似.常数大,不会被卡. 2.按块状树的方式分块.常数小,会被菊花图卡到O(n). 3.按[BZOJ1086]王室联邦的方式分块.常数小,不会被 ...

  3. BZOJ3757: 苹果树【树上莫队】

    Description ​ 神犇家门口种了一棵苹果树.苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条.由于这棵苹果树 ...

  4. 2018.09.16 bzoj3757: 苹果树(树上莫队)

    传送门 一道树上莫队. 先用跟bzoj1086一样的方法给树分块. 分完之后就可以莫队了. 但是两个询问之间如何转移呢? 感觉很难受啊. 我们定义S(u,v)" role="pre ...

  5. 【BZOJ3757】苹果树(树上莫队)

    点此看题面 大致题意: 每次问你树上两点之间路径中有多少种颜色,每次询问可能会将一种颜色\(a\)看成\(b\). 树上莫队 这题是一道树上莫队板子题. 毕竟求区间中有多少种不同的数是莫队算法的经典应 ...

  6. 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)

    2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...

  7. 树上莫队 wowow

    构建:像线性的莫队那样,依旧是按sqrt(n)为一块分块. int dfs(int x){ ; dfn[x]=++ind; ;i<=;i++) if (bin[i]<=deep[x]) f ...

  8. [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】

    题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...

  9. spoj COT2 - Count on a tree II 树上莫队

    题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的,  受益匪浅.. #include <iostream> #include < ...

  10. BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]

    传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...

随机推荐

  1. [SDOI2016] 排列计数 (组合数学)

    [SDOI2016]排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰 ...

  2. HDU 多校对抗赛 C Triangle Partition

    Triangle Partition Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Oth ...

  3. jw player学习笔记----跨域请求

    需求来源:播放器皮肤文件请求不到,被限制了. 参考官网解决方案: http://www.longtailvideo.com/support/jw-player/28844/crossdomain-fi ...

  4. VC遍历窗体控件的实现

    最近在写控制台,在设计界面按钮风格时不想通过每个按钮的ID来获取其句柄,而是通过遍历窗体所有控件,然后判断其控件类型进而来实现. 代码如下: // 遍历得到页面中的所有Button控件,依次设定其样式 ...

  5. Windows下安装Mycat-web

    Mycat-web是基于Mycat的一个性能监控工具,如:sql性能监控等. 在安装Mycat-web之前需要先安装Zookeeper: 可参考: http://blog.csdn.net/tlk20 ...

  6. [51nod1009]数字1的数量

    解题关键:数位dp,对每一位进行考虑,通过过程得出每一位上1出现的次数 1位数的情况: 在解法二中已经分析过,大于等于1的时候,有1个,小于1就没有. 2位数的情况: N=13,个位数出现的1的次数为 ...

  7. salt搭建lamp架构

    install_httpd: pkg.installed: - name: httpd httpd_running: service.running: - name: httpd - enable: ...

  8. HDOJ 3501 Calculation 2

    题目链接 分析: 要求的是小于$n$的和$n$不互质的数字之和...那么我们先求出和$n$互质的数字之和,然后减一减就好了... $\sum _{i=1}^{n} i[gcd(i,n)==1]=\le ...

  9. 【poj3420】递推式转矩阵乘法

    历史性的时刻!!! 推了一晚上!和hyc一起萌萌哒地推出来了!! 被摧残蹂躏的智商啊!!! 然而炒鸡高兴!! (请不要介意蒟蒻的内心独白..) 设a[i]为扫到第i行时的方案数. 易知,对于一行1*4 ...

  10. 【BZOJ】1692: [Usaco2007 Dec]队列变换

    [算法]字符串hash [题解] 显然如果字母互不相同,贪心取是正确的. 如果存在字母相同,那么就换成比较后缀和前缀嘛. 但是要注意,不是后缀和前缀相同就能直接跳跃,每次必须只推一位. 取模的哈希比自 ...