spoj COT2 - Count on a tree II
COT2 - Count on a tree II
http://www.spoj.com/problems/COT2/
You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.
We will ask you to perform the following operation:
- u v : ask for how many different integers that represent the weight of nodes there are on the path from u tov.
Input
In the first line there are two integers N and M. (N <= 40000, M <= 100000)
In the second line there are N integers. The i-th integer denotes the weight of the i-th node.
In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).
In the next M lines, each line contains two integers u v, which means an operation asking for how many different integers that represent the weight of nodes there are on the path from u to v.
Output
For each operation, print its result.
Example
- Input:
- 8 2
- 105 2 9 3 8 5 7 7
- 1 2
- 1 3
- 1 4
- 3 5
- 3 6
- 3 7
- 4 8
- 2 5
- 7 8
- Output:
- 4
- 4
题意:问树上两点间有多少不同的权值
树上莫队
开始狂T,发现自己竟是按节点编号划分的块!!
dfs分块。。
- #include<cmath>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- #define N 40001
- #define M 100001
- int n,m,siz,tmp;
- int hash[N],key[N];
- int front[N],to[N*],nxt[N*],tot;
- int fa[N],deep[N],id[N],son[N],bl[N],block[N];
- bool vis[N];
- int sum[N],ans[M];
- struct node
- {
- int l,r,id;
- bool operator < (node p) const
- {
- if(block[l]!=block[p.l]) return block[l]<block[p.l];
- return block[r]<block[p.r];
- }
- }e[M];
- int read(int &x)
- {
- x=; char c=getchar();
- while(c<''||c>'') c=getchar();
- while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
- }
- void add(int x,int y)
- {
- to[++tot]=y; nxt[tot]=front[x]; front[x]=tot;
- to[++tot]=x; nxt[tot]=front[y]; front[y]=tot;
- }
- void dfs(int x)
- {
- son[x]++;
- for(int i=front[x];i;i=nxt[i])
- {
- if(to[i]==fa[x]) continue;
- deep[to[i]]=deep[x]+;
- fa[to[i]]=x;
- dfs(to[i]);
- son[x]+=son[to[i]];
- }
- }
- void dfs2(int x,int top)
- {
- id[x]=++tot;
- bl[x]=top;
- block[x]=(tot-)/siz+;
- int y=;
- for(int i=front[x];i;i=nxt[i])
- {
- if(to[i]==fa[x]) continue;
- if(son[to[i]]>son[y]) y=to[i];
- }
- if(!y) return;
- dfs2(y,top);
- for(int i=front[x];i;i=nxt[i])
- {
- if(to[i]==fa[x]||to[i]==y) continue;
- dfs2(to[i],to[i]);
- }
- }
- void point(int u)
- {
- if(vis[u]) tmp-=(!--sum[hash[u]]);
- else tmp+=(++sum[hash[u]]==);
- vis[u]^=;
- }
- void path(int u,int v)
- {
- while(u!=v)
- {
- if(deep[u]>deep[v]) point(u),u=fa[u];
- else point(v),v=fa[v];
- }
- }
- int get_lca(int u,int v)
- {
- while(bl[u]!=bl[v])
- {
- if(deep[bl[u]]<deep[bl[v]]) swap(u,v);
- u=fa[bl[u]];
- }
- return deep[u]<deep[v] ? u : v;
- }
- int main()
- {
- read(n);read(m); siz=sqrt(n);
- for(int i=;i<=n;i++) read(key[i]),hash[i]=key[i];
- sort(key+,key+n+);
- key[]=unique(key+,key+n+)-(key+);
- for(int i=;i<=n;i++) hash[i]=lower_bound(key+,key+key[]+,hash[i])-key;
- int x,y;
- for(int i=;i<n;i++)
- {
- read(x); read(y);
- add(x,y);
- }
- tot=;
- dfs();
- dfs2(,);
- for(int i=;i<=m;i++)
- {
- read(e[i].l); read(e[i].r);
- e[i].id=i;
- }
- sort(e+,e+m+);
- int L=,R=,lca;
- for(int i=;i<=m;i++)
- {
- if(id[e[i].l]>id[e[i].r]) swap(e[i].l,e[i].r);
- path(L,e[i].l);
- path(R,e[i].r);
- lca=get_lca(e[i].l,e[i].r);
- point(lca);
- ans[e[i].id]=tmp;
- point(lca);
- L=e[i].l; R=e[i].r;
- }
- for(int i=;i<=m;i++) printf("%d\n",ans[i]);
- }
spoj COT2 - Count on a tree II的更多相关文章
- SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)
COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from ...
- SPOJ COT2 Count on a tree II(树上莫队)
题目链接:http://www.spoj.com/problems/COT2/ You are given a tree with N nodes.The tree nodes are numbere ...
- SPOJ COT2 Count on a tree II (树上莫队)
题目链接:http://www.spoj.com/problems/COT2/ 参考博客:http://www.cnblogs.com/xcw0754/p/4763804.html上面这个人推导部分写 ...
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
- SPOJ COT2 Count on a tree II 树上莫队算法
题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...
- SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)
题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...
- 【SPOJ10707】 COT2 Count on a tree II
SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...
- 【BZOJ2589】 Spoj 10707 Count on a tree II
BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
随机推荐
- [C++] Fucntions
Statements A break statements terminate the nearest wile, do while, for or switch statement. A break ...
- OpenCV学习4-----K-Nearest Neighbors(KNN)demo
最近用到KNN方法,学习一下OpenCV给出的demo. demo大意是随机生成两团二维空间中的点,然后在500*500的二维空间平面上,计算每一个点属于哪一个类,然后用红色和绿色显示出来每一个点 如 ...
- Alpha发布文案加美工展示
目录 团队简介 项目进展 组内分工 队员总结 后期计划 一.团队简介 二.项目进展 从选题发布到今天的Alpha发布,我们团队经历了许许多多的磨难.我们最终设计了如下的功能:首页.班级.个人.更多.打 ...
- Thunder团队第二周 - Scrum会议5
Scrum会议5 小组名称:Thunder 项目名称:爱阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- Mininet实验 MAC地址学习分析
拓扑图 学习过程分析 首先交换机A和交换机B一开始的MAC地址表都是空的. 此时主机11向主机33发送一个数据帧. 数据帧会先到达交换机A,交换机A会获得主机11的MAC地址和端口号.(此时交换机A的 ...
- 团队选题报告(i know)
一.团队成员及分工 团队名称:I know 团队成员: 陈家权:选题报告word撰写 赖晓连:ppt制作,原型设计 雷晶:ppt制作,原型设计 林巧娜:原型设计,博客随笔撰写 庄加鑫:选题报告word ...
- lintcode-173-链表插入排序
173-链表插入排序 用插入排序对链表排序 样例 Given 1->3->2->0->null, return 0->1->2->3->null 标签 ...
- Debian实验机 常用命令
1.开启中文输入法 fcitx 2. 开启无线连接 wicd 3. 远程连接 ssh root@XXX.XXX.XXX.XXX 4. 启动Ulipad ~/ulipad-master# python ...
- python爬虫:爬取网站视频
python爬取百思不得姐网站视频:http://www.budejie.com/video/ 新建一个py文件,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...
- BZOJ4028 HEOI2015公约数数列(分块)
前缀gcd的变化次数是log的,考虑对每一种gcd查询,问题变为查询一段区间是否存在异或前缀和=x/gcd. 无修改的话显然可以可持久化trie,但这玩意实在没法支持修改.于是考虑分块. 对于每一块将 ...