【BZOJ3757】苹果树(树上莫队)
大致题意: 每次问你树上两点之间路径中有多少种颜色,每次询问可能会将一种颜色\(a\)看成\(b\)。
树上莫队
这题是一道树上莫队板子题。
毕竟求区间中有多少种不同的数是莫队算法的经典应用啊。
关于将颜色\(a\)看成\(b\)
这操作其实很好处理。
只要判断\(cnt_a\)和\(cnt_b\)是否同时\(>0\)即可。
但要注意特判\(a==b\)的情况。
代码
#include<bits/stdc++.h>
#define N 50000
#define Q 100000
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,query_tot,col[N+5];
int ee,lnk[N+5];
struct edge
{
int to,nxt;
}e[(N<<1)+5];
class Class_FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (void)(FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,Fsize,stdout),Fout[(FoutSize=0)++]=ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
Class_FIO() {A=B=Fin;}
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));}
inline void writeln(int x) {if(!x) return pc('0'),pc('\n');while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);pc('\n');}
inline void clear() {fwrite(Fout,1,FoutSize,stdout),FoutSize=0;}
}F;
class Class_CaptainMotao_on_Tree//树上莫队
{
private:
#define bp(x) (((x)-1)/S+1)
#define F5(x) ((op[t=x]^=1)?(!cnt[col[t]]++&&++res):(!--cnt[col[t]]&&--res))//插入或删除一个数,其实可以合并成一个函数
int S,op[N+5],cnt[N+5],ans[N+5];//cnt统计每种数字出现次数,ans记录答案
class Class_Dfser//DFS预处理
{
private:
#define LogN 16
int cnt,Depth[N+5],fa[N+5][LogN+5];
public:
int s[(N<<1)+5],I[N+5],O[N+5];
inline void Init(int x=0,int lst=-1)
{
register int i;
for(s[I[x]=++cnt]=x,i=1;i<=LogN;++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for(i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&(Depth[e[i].to]=Depth[fa[e[i].to][0]=x]+1,Init(e[i].to,x),0);
s[O[x]=++cnt]=x;
}
inline int LCA(int x,int y)
{
register int i;
for(Depth[x]<Depth[y]&&swap(x,y),i=0;Depth[x]^Depth[y];++i) ((Depth[x]^Depth[y])&(1<<i))&&(x=fa[x][i]);
if(!(x^y)) return x;
for(i=LogN;~i;--i) fa[x][i]^fa[y][i]&&(x=fa[x][i],y=fa[y][i]);
return fa[x][0];
}
}D;
struct Query
{
int l,r,pos,bl,flag,s1,s2;
Query(int x=0,int y=0,int p=0,int b=0,int f=0,int t1=0,int t2=0):l(x),r(y),pos(p),bl(b),flag(f),s1(t1),s2(t2){}
inline friend bool operator < (Query x,Query y) {return x.bl^y.bl?x.bl<y.bl:(x.bl&1?x.r<y.r:x.r>y.r);}
}q[Q+5];
public:
inline void Solve()
{
int i,x,y,s1,s2,z,t,L=1,R=0,res=0;
for(D.Init(),S=sqrt(n),i=1;i<=query_tot;++i)
{
F.read(x),F.read(y),F.read(s1),F.read(s2),D.I[x]>D.I[y]&&swap(x,y),//读入,保证I[x]<=I[y]
q[i]=(z=D.LCA(x,y))^x?Query(D.O[x],D.I[y],i,bp(D.O[x]),z,s1,s2):Query(D.I[x],D.I[y],i,bp(D.I[x]),0,s1,s2);//存储询问
}
for(sort(q+1,q+query_tot+1),i=1;i<=query_tot;++i)//处理询问
{
while(R<q[i].r) F5(D.s[++R]);while(L>q[i].l) F5(D.s[--L]);while(R>q[i].r) F5(D.s[R--]);while(L<q[i].l) F5(D.s[L++]);//移动区间
q[i].flag&&F5(q[i].flag),ans[q[i].pos]=res-(q[i].s1^q[i].s2&&cnt[q[i].s1]&&cnt[q[i].s2]),q[i].flag&&F5(q[i].flag);//判断是否要增加LCA的贡献,并处理将颜色a看成b的情况
}
for(i=1;i<=query_tot;++i) F.writeln(ans[i]);//输出答案
}
}C;
int main()
{
register int i,x,y;
for(F.read(n),F.read(query_tot),i=1;i<=n;++i) F.read(col[i]);
for(i=1;i<=n;++i) F.read(x),F.read(y),add(x,y),add(y,x);
return C.Solve(),F.clear(),0;
}
【BZOJ3757】苹果树(树上莫队)的更多相关文章
- [BZOJ3757]苹果树(树上莫队)
树上莫队共有三种写法: 1.按DFS序列分块,和普通莫队类似.常数大,不会被卡. 2.按块状树的方式分块.常数小,会被菊花图卡到O(n). 3.按[BZOJ1086]王室联邦的方式分块.常数小,不会被 ...
- 【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 ...
- 树上莫队 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 < ...
随机推荐
- [转]Using OData from ASP.NET
本文转自:http://www.drdobbs.com/windows/using-odata-from-aspnet/240168672 By Gastón Hillar, July 01, 201 ...
- PHP学习4——面向对象
主要内容: 创建类 成员方法 构造方法 析构方法 封装 继承 接口 多态 静态成员 常用关键字 常用魔术方法 从PHP5开始引入了面向对象的全部机制,面向对象的特性符合软件工程的3个目标:重用性,灵活 ...
- java向上转型的问题
import java.util.Arrays;import java.util.HashSet;import java.util.Set;class A{ private String s1 = & ...
- 域名解析成功后,怎样访问服务器上Eclipse中的Web工程
右击工程选择Export-->选择Web文件夹下的WAR file-->Destination下选择文件存放的地址-->Finish就可以获得WAR文件了然后将WAR文件放到tomc ...
- 把一个项目a生成后放在另一个项目b使用(b项目是例子中的ScreenWebPage_Tool)
a项目属性---生成事件---后期生成事件命令行 xcopy /r /y $(TargetDir)*.* $(SolutionDir)ScreenWebPage_Tool\bin\Debug\* ...
- 02HTML-<img>
一.img的属性:alt/title alt属性是替换名字,是给搜索引擎抓取使用,当图片显示不出来时,就会显示出alt的内容: title 属性是提示文字,当鼠标移到图片上的时候会显示出来,大部分的标 ...
- 前端学习之路之CSS (二)
Infi-chu: http://www.cnblogs.com/Infi-chu/ id选择器id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式,CSS 中 id 选择器以 &quo ...
- CentOS新增硬盘,重新扫描总线
Centos 新增硬盘以后,系统不能自动进行识别. 1. 由于不知道新增硬盘挂载的位置,可以先查看现有硬盘挂载的适配器. [root@localhost ~]# ls -l /sys/block/sd ...
- ArcEngine交互画线
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...
- shp文件导入mysql5.6.15
百度了一下 方法大致相同,就是提供的资源都缺斤短两还在细节上有差异.所以上传一份正确的. 0.将cygwin1.dll拷贝到system32目录下面1.将shp以及shp的相关文件和DOShere的d ...