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 ...
随机推荐
- (转载)IE8+兼容经验小结
本文分享下我在项目中积累的IE8+兼容性问题的解决方法.根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的方式写的,然后下面的几点都关注过,那么基本上很大一部分IE8+兼容性问题都OK ...
- ACM 第十九天
积性函数 积性函数线性筛,筛素数,u(n),欧拉函数: vis[]=vis[]=,mu[]=,phi[]=; ;i<=N;++i){ ,phi[i]=i-,prime[++cnt]=i; ,k= ...
- OSG学习:响应键盘鼠标示例
示例功能:示例里面有两个模型,一个是牛,另一个是飞机.鼠标右键时牛和飞机都隐藏,鼠标左键双击时牛和飞机都显示,按键盘上面的LEFT键,显示牛,按键盘上面的RIGHT键显示飞机.其中显示与隐藏节点使用的 ...
- phpcms V9如何判断用户是否登录以及登陆后的标签写法问题
首先要获取userid {php$userid=param::get_cookie('_userid');} 然后再判断是否为空 {if $userid}...这里写已经登录之后的代码...{els ...
- SQL SERVER技术内幕之10 事务并发
1.事务 1.1事务的定义 事务是作为单个工作单元而执行的一系列操作.定义事务边界有显式和隐式两种.显式事务的定义以BEGIN TRAN作为开始,以COMMIT TRAN提交事务,以ROLLBACK ...
- java 基础--继承--007
1,子类只能继承父类所有非私有成员 2,子类不能继承父类的构造方法,但可以通过super去访问父类构造方法 3,子类成员变量和父类成员变量名称不一样,如果一样类似于重写,按子类处理,如果一样,就近原则 ...
- C#中的is和as操作符
在C#语言中进行类型转换的操作符is和as.is和as都是强制类型转换,但这两者有什么相同之处和不同之处呢?在使用is和as需要注意哪些事项?下面我们从简单的代码示例去探讨这个简单的问题.注:此博文只 ...
- Matlab中save与load函数的使用
用save函数,可以将工作空间的变量保存成txt文件或mat文件等. 比如: save peng.mat p j 就是将工作空间中的p和j变量保存在peng.mat中. 用load函数,可以将数据读入 ...
- 【bzoj4300】绝世好题 dp
题目描述 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). 输入 输入文件共2行. 第一行包括一个整数n. 第二行包括n个 ...
- 【bzoj1704】[Usaco2007 Mar]Face The Right Way 自动转身机 贪心
题目描述 农夫约翰有N(1≤N≤5000)只牛站成一排,有一些很乖的牛朝前站着.但是有些不乖的牛却朝后站着.农夫约翰需要让所有的牛都朝前站着.幸运的是约翰最近买了一个自动转身机.这个神奇的机器能使K( ...