SP10707 COT2 - Count on a tree II

题意:

给定 n 个结点的树,每个结点有一种颜色。
m 次询问,每次询问给出 u,v,回答 u,v 之间的路径上的结点的不同颜色数。
1< = n < =4*10^4
1< = m < =10^5

题解:

树上莫队的裸题
但是裸题也是很难。。emm
我这里有比较详细的讲解
我大体总结一下就是:欧拉序实现树转为线性结构,然后在上面跑莫队
当然还要考虑v是u的子树,u和v不在一个子树等等各种情况
lca可以用树剖求,也可以lca
详细看代码

代码:

代码不是自己打的,等我把树剖复习完再重新打一遍

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#define N 200000
using namespace std;
struct node
{int l,r,ll,rr,id,lca;
}q[N+5];
int n,m,a[N+5],st[N+5],ed[N+5],dfn[N+5],f[N+5],num,size[N+5],his[N+5],dep[N+5],son[N+5],top[N+5],c[N+5],tmp,block,l=1,r,use[N+5],ans[N+5],data[N+5];
vector <int> d[N+5];
void dfs1(int u,int fa)  //树剖第一次深搜
{f[u]=fa;st[u]=++num;size[u]=1;his[num]=u;dep[u]=dep[fa]+1;vector <int>::iterator it;for (it=d[u].begin();it!=d[u].end();it++){int v=(*it);if (v==fa)continue;dfs1(v,u);size[u]+=size[v];if (size[v]>size[son[u]])son[u]=v;}ed[u]=++num;his[num]=u;
}
void dfs2(int u,int to)   //树剖第二次深搜
{top[u]=to;if (son[u])dfs2(son[u],to);vector <int>::iterator it;for (it=d[u].begin();it!=d[u].end();it++){int v=(*it);if (v!=son[u]&&v!=f[u])dfs2(v,v);}
}
int Lca(int x,int y)   //树剖求lca
{while (top[x]!=top[y]){if (dep[top[x]]<dep[top[y]])swap(x,y);x=f[top[x]];}if (dep[x]>dep[y])swap(x,y);return x;
}
void add(int x)
{tmp+=(++c[a[x]]==1);
}
void del(int x)
{tmp-=(--c[a[x]]==0);
}
void calc(int x)     //对点进行加入或删除
{(use[x]==0)?add(x):del(x);use[x]^=1;
}
int cmp(node x,node y)   //排序
{return (x.ll==y.ll)?(x.ll%2==1?x.r<y.r:x.r>y.r):x.l<y.l;
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&a[i]),data[i]=a[i];sort(data+1,data+n+1);for(int i=1;i<=n;i++)a[i]=lower_bound(data+1,data+n+1,a[i])-data;  //离散化int x,y;for (int i=1;i<n;i++){scanf("%d%d",&x,&y);d[x].push_back(y);d[y].push_back(x);}dfs1(1,0); dfs2(1,1);block=n*2/sqrt(m*2/3);for (int i=1;i<=m;i++){scanf("%d%d",&x,&y);if (st[x]>st[y])swap(x,y);  //保证stx<styq[i].id=i;q[i].lca=Lca(x,y);  if (q[i].lca==x)    //x,y在以x为根的子树中{q[i].l=st[x];q[i].r=st[y];q[i].ll=st[x]/block;q[i].rr=st[y]/block;q[i].lca=0;}else{q[i].l=ed[x];q[i].r=st[y];q[i].ll=ed[x]/block;q[i].rr=st[y]/block;}}sort(q+1,q+m+1,cmp);for (int i=1;i<=m;i++){while (l>q[i].l)calc(his[--l]);while (r<q[i].r)calc(his[++r]);while (l<q[i].l)calc(his[l++]);while (r>q[i].r)calc(his[r--]);if (q[i].lca)calc(q[i].lca);ans[q[i].id]=tmp;if (q[i].lca)calc(q[i].lca);}for (int i=1;i<=m;i++)printf("%d\n",ans[i]);return 0;
}

SP10707 COT2 - Count on a tree II相关推荐

  1. SP10707 COT2 - Count on a tree II【树上莫队】

    传送门 给定一颗无根树,求树上两点路径上的节点有多少不同的数字 可以离线 分析 前提,能够通过某种操作,将树上路径问题,转化成区间问题 这样,类似于求区间不同数,区间众数,区间mex等操作就能通过莫队 ...

  2. 【莫队/树上莫队/回滚莫队】原理详解及例题:小B的询问(普通莫队),Count on a tree II(树上莫队),kangaroos(回滚莫队)

    文章目录 问题引入 介绍莫队算法及其实现过程 时间复杂度 莫队算法适用范围 莫队奇偶优化 普通莫队:小B的询问 树上莫队:SP10707 COT2 - Count on a tree II 回滚莫队: ...

  3. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  4. 【SPOJ COT2】Count on a tree II,树上莫队

    Time:2016.09.07 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 第一次写树上莫队 被char哥怒裱一通 实际上还是比较简单的 序列的相关维护问题转移到树上一般都要涉及 ...

  5. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7669  Solved: 1894 [Sub ...

  6. BZOJ2588 Count on a tree DFS序+LCA+值域主席树

    Count on a tree 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答 ...

  7. [SPOJ-COT]Count on a tree

    [SPOJ-COT]Count on a tree 题面 You are given a tree with N nodes. The tree nodes are numbered from 1 t ...

  8. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

  9. Count on a tree

    bzoj  2588: Spoj 10628. Count on a tree http://www.lydsy.com/JudgeOnline/problem.php?id=2588 Descrip ...

最新文章

  1. GIT如何查看本地分支与远程分支的关联配置(git branch --set-upstream)
  2. nginx+keepalived
  3. 为什么要在linux命令前加上 ./
  4. 美国康奈尔大学计算机科学的教授,美国康奈尔大学教授Robbert van Renesse访问并做学术报告...
  5. 黄聪: 50 个 Bootstrap 插件
  6. 天堂里的游戏(51Nod-1417)
  7. 隐藏我的电脑中的多余图标
  8. Redis集群环境下分布式锁方案-RedLock算法
  9. Ext JS 6学习文档–第1章–ExtJS入门指南
  10. 支教日记软件测试,烟酒行销售实习日志(74页)-原创力文档
  11. 永远做重要而不紧急的事
  12. 加性高斯白噪声信道的信道容量
  13. linux lxde桌面快捷键,LXde 桌面有两下啊
  14. 戴尔笔记本电脑怎下载c语言,戴尔笔记本电脑如何下载驱动
  15. IDC网络传输优化的罪与罚
  16. android分区卸载命令行,Android ADB命令 将apk安装到系统应用及删除方法
  17. ACM投稿版权信息去除问题
  18. 图解算法:KMP算法
  19. win7系统安装信息服务器不可用怎么办,Win7电脑RPC服务器不可用怎么办 RPC服务器不可用解决方法...
  20. 程序员笑话集:bug跟蚊子的相似之处

热门文章

  1. 你是不是在混日子,看着一点就知道了
  2. 每日一笑 | 在地铁上被老奶奶让座是一种什么样的体验?
  3. 普通人和程序员看到的树
  4. 12如何隐藏dock栏_iPhone边框“变色”壁纸,隐藏Dock栏
  5. matlab中给图像加几个矩形框_没想到!PPT中的这个效果,用好了,简直就是渣图美化器...
  6. python安装详细步骤mac_Mac安装python3的方法步骤
  7. adf盖怎么打开_罐头好吃盖难开,学会这几招,再不靠蛮力了,女生也轻松拧开...
  8. 计算机表演赛新疆赛区,【图】第二十六届中国儿童青少年威盛中国芯HTC计算机表演赛“中国电信天翼杯”新疆赛区总决赛圆满结束_乌鲁木齐教育信息网...
  9. 百度网页移动端html,百度移动端开始用网站品牌名代替网址显示
  10. egg前面加什么_国威说阀:阀门前面为什么加国标美标日标之类的?