题意

给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数。

n=40000,m=100000

Sol

树上莫队模板题

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
const int _(1e5 + 5);
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} int n, m, first[_], cnt, w[_], o[_], len;
int dfn[_], st[20][_], lg[_], deep[_], idx, fa[_];
int S[_], bl[_], blo, num, ans[_], sum[_], vis[_], Ans;
struct Edge{
int to, next;
} edge[_];
struct Query{
int l, r, id; IL int operator <(RG Query B) const{
return bl[l] == bl[B.l] ? dfn[r] < dfn[B.r] : bl[l] < bl[B.l];
}
} qry[_]; IL void Add(RG int u, RG int v){
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
} IL void Dfs(RG int u){
dfn[u] = ++idx, st[0][idx] = u; RG int l = S[0];
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].to;
if(dfn[v]) continue;
deep[v] = deep[u] + 1, fa[v] = u;
Dfs(v);
if(S[0] - l >= blo) for(++num; S[0] != l; --S[0]) bl[S[S[0]]] = num;
st[0][++idx] = u;
}
S[++S[0]] = u;
} IL void Chk(RG int &x, RG int u, RG int v){
x = deep[u] < deep[v] ? u : v;
} IL int LCA(RG int u, RG int v){
u = dfn[u], v = dfn[v];
if(u > v) swap(u, v);
RG int log2 = lg[v - u + 1], t;
Chk(t, st[log2][u], st[log2][v - (1 << log2) + 1]);
return t;
} IL void Update(RG int x){
if(vis[x]) --sum[w[x]], Ans -= (!sum[w[x]]);
else Ans += (!sum[w[x]]), ++sum[w[x]];
vis[x] ^= 1;
} IL void Modify(RG int u, RG int v){
while(u != v){
if(deep[u] > deep[v]) swap(u, v);
Update(v), v = fa[v];
}
} int main(RG int argc, RG char* argv[]){
len = n = Input(), m = Input(), blo = sqrt(n);
for(RG int i = 1; i <= n; ++i) o[i] = w[i] = Input(), first[i] = -1;
sort(o + 1, o + len + 1), len = unique(o + 1, o + len + 1) - o - 1;
for(RG int i = 1; i <= n; ++i) w[i] = lower_bound(o + 1, o + len + 1, w[i]) - o;
for(RG int i = 1, u, v; i < n; ++i)
u = Input(), v = Input(), Add(u, v), Add(v, u);
Dfs(1);
if(S[0]) for(++num; S[0]; --S[0]) bl[S[S[0]]] = num;
for(RG int i = 2; i <= idx; ++i) lg[i] = lg[i >> 1] + 1;
for(RG int j = 1; j <= lg[idx]; ++j)
for(RG int i = 1; i + (1 << j) - 1 <= idx; ++i)
Chk(st[j][i], st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
for(RG int i = 1; i <= m; ++i){
qry[i] = (Query){Input(), Input(), i};
if(dfn[qry[i].l] > dfn[qry[i].r]) swap(qry[i].l, qry[i].r);
}
sort(qry + 1, qry + m + 1);
RG int lca = LCA(qry[1].l, qry[1].r);
Modify(qry[1].l, qry[1].r);
Update(lca), ans[qry[1].id] = Ans, Update(lca);
for(RG int i = 2; i <= m; ++i){
Modify(qry[i - 1].l, qry[i].l), Modify(qry[i - 1].r, qry[i].r);
lca = LCA(qry[i].l, qry[i].r);
Update(lca), ans[qry[i].id] = Ans, Update(lca);
}
for(RG int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
return 0;
}

SPOJ:COT2 Count on a tree II的更多相关文章

  1. SPOJ 10707 COT2 - Count on a tree II

    思路 树上莫队的题目 每次更新(u1,u2)和(v1,v2)(不包括lca)的路径,最后单独统计LCA即可 代码 #include <cstdio> #include <cstrin ...

  2. spoj COT2 - Count on a tree II

    COT2 - Count on a tree II http://www.spoj.com/problems/COT2/ #tree You are given a tree with N nodes ...

  3. 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  ...

  4. COT2 - Count on a tree II(树上莫队)

    COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...

  5. 【SPOJ10707】 COT2 Count on a tree II

    SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...

  6. 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 ...

  7. SPOJ COT2 Count on a tree II (树上莫队)

    题目链接:http://www.spoj.com/problems/COT2/ 参考博客:http://www.cnblogs.com/xcw0754/p/4763804.html上面这个人推导部分写 ...

  8. SPOJ COT2 Count on a tree II 树上莫队算法

    题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...

  9. SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)

    题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...

随机推荐

  1. jQuery 与 js的入口函数写法

    //js的入口函数执行要比jQuery的入口函数执行得晚一些. //jq的入口函数会等待页面的加载完成才执行,但是不会等待图片的加载. //js的入口函数会等待页面加载完成,并且等待图片加载完成才开始 ...

  2. (一)使用appium之前为什么要安装nodejs???

    很多人在刚接触appium自动化时,可能会像我一样,按照教程搭建好环境后,却不知道使用appium之前为什么要用到node.js,nodejs到底和appium是什么关系,对nodejs也不是很了解, ...

  3. 高阶篇:4.1.2.2)产品部件级别的QFDII

    本章目的:介绍产品部件级别的QFDII编写方法. 1.前言 这章接前面总成级别的QFDII. 产品部件级别的QFDII,其实就是将部件QFDII所得到的设计要求,进一步分配给部件其装配层级的零部件中. ...

  4. django Form数据读取问题

    1.在我学习django的过程中,我学习到了一个关于表单验证的问题 2.我们从前端post一个表单,通过urls配置,传给对应的view方法 3.然后再传给Form验证 4.一开始我是很好奇,在vie ...

  5. webpack 打包之后,两行溢出没有效果

    原因:发现-webkit-box-orient:vertical;并未设置成功解决:-webkit-box-orient: vertical; 加上注释包裹 .item-title { overflo ...

  6. pandas数据清洗

    1.我已安装好Anavonda3.5.所以我只用打开"jupyter notebook",然后打开浏览器 然后点击右侧的“new",然后打开python3

  7. oracle12c之二 控制PDB中SGA 与 PGA 内存使用

    oracle12c之 控制pdb中sga 与 pga 内存使用 Memory Management using Resource Manager Oracle数据库资源管理器(资源管理器)现在可以在多 ...

  8. idea没有tomcat选项在setting也没有Application Servers

    原因:dea未正常关闭,重启后发现,Tomcat的选项不见了,File->Setting->Build,Excution,Deployment里面Application Servers也不 ...

  9. Java解析excel文档并以List<T>输出

    /********************************************************工具类start*********************************** ...

  10. Android SurfaceFlinger

    Android 系统启动过程Activity 创建过程Activity 与 Window 与 View 之间的关系 Android 系统从按下开机键到桌面,从桌面点击 App 图标到 Activity ...