原题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3757

苹果树

Description

神犇家门口种了一棵苹果树。苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条。由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色。我们用一个到n之间的正整数来表示一种颜色。树上一共有n个苹果。每个苹果都被编了号码,号码为一个1到n之间的正整数。我们用0代表树根。只会有一个苹果直接根。

有许许多多的人来神犇家里膜拜神犇。可神犇可不是随便就能膜拜的。前来膜拜神犇的人需要正确回答一个问题,才能进屋膜拜神犇。这个问题就是,从树上编号为u的苹果出发,由树枝走到编号为v的苹果,路径上经过的苹果一共有多少种不同的颜色(包括苹果u和苹果v的颜色)?不过神犇注意到,有些来膜拜的人患有色盲症。具体地说,一个人可能会认为颜色a就是颜色b,那么他们在数苹果的颜色时,如果既出现了颜色a的苹果,又出现了颜色b的苹果,这个人只会算入颜色b,而不会把颜色a算进来。

神犇是一个好人,他不会强人所难,也就会接受由于色盲症导致的答案错误(当然答案在色盲环境下也必须是正确的)。不过这样神犇也就要更改他原先数颜色的程序了。虽然这对于神犇来说是小菜一碟,但是他想考验一下你。你能替神犇完成这项任务吗?

Input

输入第一行为两个整数n和m,分别代表树上苹果的个数和前来膜拜的人数。
接下来的一行包含n个数,第i个数代表编号为i的苹果的颜色Coli。

接下来有n行,每行包含两个数x和y,代表有一根树枝连接了苹果x和y(或者根和一个苹果)。

接下来有m行,每行包含四个整数u、v、a和b,代表这个人要数苹果u到苹果v的颜色种数,同时这个人认为颜色a就是颜色b。如果a=b=0,则代表这个人没有患色盲症。

Output

输出一共m行,每行仅包含一个整数,代表这个人应该数出的颜色种数。

Sample Input

5 3
1 1 3 3 2
0 1
1 2
1 3
2 4
3 5
1 4 0 0
1 4 1 3
1 4 1 2

Sample Output

2
1
2

HINT

0<=x,y,a,b<=N

N<=50000

1<=U,V,Coli<=N

M<=100000

题解

树上莫队模板。

算法介绍的话,写在莫队总结里好了,题解就这样吧。。。

代码
#include<bits/stdc++.h>
#define R register int
using namespace std;
const int M=1e5+5;
struct sd{int f,t,a,b,id;};
sd ask[M];
bool vis[M];
int col[M],team[M],n,m,siz[M],dad[M],dep[M],son[M],top[M],sta[M],id[M],tot,zhan,big,num,ans[M],root,cot[M],hh;
bool operator <(sd a,sd b){return team[a.f]==team[b.f]?id[a.t]<id[b.t]:team[a.f]<team[b.f];}
vector<int>mmp[M];
void in()
{int a,b;R i;scanf("%d%d",&n,&m);big=(int)pow(n,6.0/10.0);for(i=1;i<=n;++i)scanf("%d",&col[i]);for(i=1;i<=n;++i){scanf("%d%d",&a,&b),mmp[a].push_back(b),mmp[b].push_back(a);if(!a||!b)root=a?a:b;}
}
int dfs1(int v,int f,int d)
{id[v]=++tot;dad[v]=f;siz[v]=1;dep[v]=d;int bs=0,to,tmp,now=zhan;for(int i=mmp[v].size()-1;i>=0;--i){to=mmp[v][i];if(to==f)continue;tmp=dfs1(to,v,d+1);if(tmp>bs)son[v]=to,bs=tmp;siz[v]+=tmp;if(zhan-now>=big){++num;while(zhan!=now)team[sta[zhan--]]=num;}}sta[++zhan]=v;return siz[v];
}
void dfs2(int v,int t)
{top[v]=t;int to;if(son[v])dfs2(son[v],t);for(int i=mmp[v].size()-1;i>=0;--i){to=mmp[v][i];if(to==dad[v]||to==son[v])continue;dfs2(to,to);}
}
int lca(int x,int y)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=dad[top[x]];}return dep[x]<dep[y]?x:y;
}
void rev(int x){if(vis[x]&&--cot[col[x]]==0)hh--;if(!vis[x]&&++cot[col[x]]==1)hh++;vis[x]^=1;}
void walk(int x,int y){while(x!=y){if(dep[x]<dep[y])swap(x,y);rev(x);x=dad[x];}}
void ac()
{R i;dfs1(root,0,1);dfs2(root,root);if(zhan){num++;while(zhan){team[sta[zhan--]]=num;}}for(i=1;i<=m;++i){scanf("%d%d%d%d",&ask[i].f,&ask[i].t,&ask[i].a,&ask[i].b),ask[i].id=i;if(id[ask[i].f]>id[ask[i].t])swap(ask[i].f,ask[i].t);}sort(ask+1,ask+1+m);int F=1,T=1,lc,p;for(i=1;i<=m;++i){walk(F,ask[i].f);walk(T,ask[i].t);F=ask[i].f,T=ask[i].t;lc=lca(F,T);rev(lc);p=0;if(ask[i].a!=ask[i].b&&cot[ask[i].a]&&cot[ask[i].b])p=1;ans[ask[i].id]=hh-p;rev(lc);}for(i=1;i<=m;++i)printf("%d\n",ans[i]);
}
int main()
{in();ac();return 0;
}

BZOJ3757 苹果树相关推荐

  1. P2015 二叉苹果树

    传送门 这道题要用到链式前向星... 非常标准的树形背包DP 只要理解了,题就不难 只要理解了...... 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树 ...

  2. 苹果树的故事(转发的)

    一棵苹果树,终于结果了. 第一年,它结了十个苹果,九个被拿走,自己得到一个.对此,苹果树愤愤不平,于是自断经脉,拒绝成长.第二年,它结了五个苹果,四个被拿走,自己得到一个."哈哈,去年我得到 ...

  3. 洛谷 P2015 二叉苹果树

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  4. 二叉苹果树(树型DP+背包)

    二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号 ...

  5. JZOJ 1016. 【PKU3321】苹果树

    Description 你家门前种了一棵苹果树,每年秋天,树上都结满了苹果,你非常喜欢吃苹果,所以一直精心照料着苹果树. 苹果树有N个分叉,分叉之间由枝干相连,你把分叉用1到N来标记,树根必须记为1. ...

  6. 洛谷2015 二叉苹果树 树形DP

    https://www.luogu.org/problemnew/show/P2015 二叉苹果树 时间限制: 1 Sec  内存限制: 128 MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 ...

  7. 苹果树(线段树+Dfs序)

    1228 苹果树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结 ...

  8. 兰州大学第一届 飞马杯 ★★快乐苹果树★★ 树链剖分 + 懒标记 + 树状数组

    传送门 文章目录 题意: 思路: 题意: 思路: 第一次听说树链剖分能在fa[top[i]]fa[top[i]]fa[top[i]]的地方加懒标记,学到了学到了. 首先不能被题目吓住,这个题目仔细剖析 ...

  9. 洛谷P2015 二叉苹果树【树形dp】

    P2015 二叉苹果树 时间限制 1.00s 内存限制 125.00MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点 ...

  10. 西北农林科技大学计算机老师 癌症,西北农林科大攻克苹果树“癌症”

    由西北农林科技大学主持完成的"苹果树腐烂病等重大病害生物学及防治技术研究"项目,12月12日在陕西杨凌农科城通过鉴定.鉴定委员认为该成果在苹果树腐烂病菌.轮纹病菌的生物学基础研究方 ...

最新文章

  1. 页面静态化2 --- 使用PHP缓存机制来完成页面静态化(上)(ob_flush和flush函数区别用法)...
  2. 花高价招来的阿里P8,我从他那里总结了8大硬核能力,4个经典案例,真香
  3. 可以以数据内容当列名来统计数据
  4. java 5 线程 睡眠,Java线程之线程的调度-休眠
  5. git配置取消代理_「高手」如何优雅的解决 git 超时
  6. python识别文字tesseract
  7. 《Redis实战》一2.2 使用Redis实现购物车
  8. SQL连接两张或多张表
  9. headfirst python完整高清思维导图
  10. 一梦江湖获取服务器信息卡住,一梦江湖手游2021年8月6日更新公告
  11. 迅雷版权限制无法下载破解
  12. 计算机主机显卡安装,电脑显卡驱动怎么安装
  13. 数字排在最前,英文字母其次,汉字则按照拼音进行排序,获取中文首字母
  14. hy-bridge:一款简洁安全可靠的Hybrid框架
  15. 免费下载思科CCNP 642-802考试题库
  16. FCPX:快速时尚视频转场Stupid Raisins Fast Pop下载
  17. 数学建模学习笔记(清风)——插值算法
  18. android中Picasso显示网络图片
  19. HM编码器代码阅读(20)——与变换量化有关的其他知识
  20. gateway的配置文件

热门文章

  1. Flume 1.8.0 开发者指南(中文教程)-个人翻译版
  2. 简单的全局异常统一处理
  3. [解决]RESTEASY003215: could not find writer for content-type text/html type: java.lang.String
  4. flask第九篇——url_for【2】
  5. SpringMVC中的返回值问题之三返回list类型和map类型
  6. 精通JavaScript--06设计模式:结构型
  7. C# 在word中查找及替换文本
  8. c语言如何交替打印大小写字母,C/C++语言实现两个线程交替打印奇偶数
  9. 解决:本地计算机上的MySQL80服务启动后停止,某些服务在未由其他服务或者程序使用时将自动停止
  10. Parallel垃圾回收器总结