$n$ 个点的树,数一条链上有多少不同的点

sol:

树上莫队

首先,王室联邦分块

记 $(cu,cv)$ 为当前的链,$(qu,qv)$ 为当前询问的链,维护一个 $vis$ 数组表示“当前点在/不在当前链上”,每次暴力从 $cu,qu$ 爬到他们的 lca,从 $cv,qv$ 爬到他们的 lca,特盘一下 $qu,qv$ 的 lca 就可以了

#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define rep(i, s, t) for (register int i = (s), i__end = (t); i <= i__end; ++i)
#define dwn(i, s, t) for (register int i = (s), i__end = (t); i >= i__end; --i)
inline int read() {
int x = , f = ; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
for (; isdigit(ch); ch = getchar()) x = * x + ch - '';
return x * f;
}
const int maxn = ;
int n, m, b[maxn], a[maxn], blk, bcnt;
vector<int> G[maxn];
int fa[maxn], dep[maxn];
namespace splca {
int size[maxn], top[maxn];
void dfs1(int x) {
size[x] = ;
for(auto to : G[x]) {
if(to == fa[x]) continue;
fa[to] = x;
dfs1(to); size[x] += size[to];
}
}
void dfs2(int x, int col) {
int k = ; top[x] = col;
for(auto to : G[x])
if(to != fa[x] && size[to] > size[k]) k = to;
if(!k) return;
dfs2(k, col);
for(auto to : G[x])
if(to != fa[x] && to != k) 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 = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
}
void lca_init() {splca::dfs1(); splca::dfs2(, );}
int lca(int x, int y) {return splca::lca(x, y);} int size[maxn], bl[maxn], q[maxn], top;
int dfs2(int x) {
int cur = ;
for(auto to : G[x]) {
if(to == fa[x]) continue;
dep[to] = dep[x] + ;
cur += dfs2(to);
if(cur >= blk) {
while(cur--) bl[q[--top]] = bcnt;
bcnt++;
}
}
q[++top] = x;
return cur + ;
}
int ans[maxn], vis[maxn], inq[maxn];
struct Ques {
int u, v, fl, fr, id;
bool operator < (const Ques &b) const {
return fl == b.fl ? fr < b.fr : fl < b.fl;
}
}qs[maxn];
int now;
void move(int &x) {
if(inq[x]){
if(--vis[a[x]] == ) now--;
}
else if(++vis[a[x]] == ) now++;
inq[x] ^= ;
x = fa[x];
}
int main() {
n = read(), m = read();
blk = sqrt(n);
rep(i, , n) b[i] = a[i] = read();
sort(b + , b + n + );
rep(i, , n) a[i] = lower_bound(b+, b+n+, a[i]) - b;
rep(i, , n) {
int u = read(), v = read();
G[u].push_back(v); G[v].push_back(u);
} lca_init(); dep[] = ; dfs2();
while(top) bl[q[--top]] = bcnt;
rep(i, , m) {
int v = read(), u = read();
if(bl[v] > bl[u]) swap(u, v);
qs[i] = (Ques){v, u, bl[v], bl[u], i};
//cout << v << " " << u << " " << bl[v] << " " << bl[u] << endl;
}
sort(qs + , qs + m + );
int cu = , cv = ;
rep(i, , m) {
int nu = qs[i].u, nv = qs[i].v;
int anc = lca(cu, nu);
while(cu != anc) move(cu);
while(nu != anc) move(nu);
anc = lca(cv, nv);
while(cv != anc) move(cv);
while(nv != anc) move(nv);
cv = qs[i].v, cu = qs[i].u;
anc = lca(cv, cu);
ans[qs[i].id] = now + (!vis[a[anc]]);
}
rep(i, , m) printf("%d\n",ans[i]);
}

Count On A Tree II.的更多相关文章

  1. 【SPOJ10707】 COT2 Count on a tree II

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

  2. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

  3. 【BZOJ2589】[SPOJ10707]Count on a tree II

    [BZOJ2589][SPOJ10707]Count on a tree II 题面 bzoj 题解 这题如果不强制在线就是一个很\(sb\)的莫队了,但是它强制在线啊\(qaq\) 所以我们就用到了 ...

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

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

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

  6. AC日记——Count on a tree II spoj

    Count on a tree II 思路: 树上莫队: 先分块,然后,就好办了: 来,上代码: #include <cmath> #include <cstdio> #inc ...

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

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

  9. 「SPOJ10707」Count on a tree II

    「SPOJ10707」Count on a tree II 传送门 树上莫队板子题. 锻炼基础,没什么好说的. 参考代码: #include <algorithm> #include &l ...

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

随机推荐

  1. Map中object转换成boolean类型

    Ajax请求查询数据之后,返回的是map类型, resultMap.put("flag", flag); 在接收到数据之后判断时,转换出现异常,导致页面点击按钮之后,页面没有反应, ...

  2. Loadrunder之脚本篇——参数化在场景中的运用

    Action() { lr_eval_string("{NewParam}"); lr_eval_string("{NewParam}"); return 0; ...

  3. OpenGL学习进程(5)第三课:视口与裁剪区域

    本节是OpenGL学习的第三个课时,下面介绍如何运用显示窗体的视口和裁剪区域:     (1)知识点引入:     1)问题现象: 当在窗体中绘制图形后,拉伸窗体图形形状会发生变化: #include ...

  4. Linux脚本程序包及安装

    概述 脚本程序并不多见,所以在软件包分类中并没有把它列为一类.它更加类似于 Windows 下的程序安装,有一个可执行的安装程序,只要运行安装程序,然后进行简单的功能定制选择(比如指定安装目录等),就 ...

  5. 关于dispatch_semaphore的使用

    dispatch_semaphore是GCD用来同步的一种方式,与他相关的共有三个函数,分别是 dispatch_semaphore_create,dispatch_semaphore_signal, ...

  6. Nginx配置指令的执行顺序

    rewrite阶段 rewrite阶段是一个比较早的请求处理阶段,这个阶段的配置指令一般用来对当前请求进行各种修改(比如对URI和URL参数进行改写),或者创建并初始化一系列后续处理阶段可能需要的Ng ...

  7. 友盟分享适配iOS9

    在新发布的iOS9系统上围绕用户数据的安全性和体验新增了一些安全特性,同时也影响了应用的实现以及集成方式,为了保证良好的稳定性和体验,需要做如下处理: 1.  HTTP传输安全 以iOS9 SDK编译 ...

  8. 高通Android display分析【转】

    本文转载自:http://blog.csdn.net/zhangchiytu/article/details/6777039 高通7系列硬件架构分析 如上图,高通7系列 Display的硬件部分主要由 ...

  9. centos7 下安装eclipse

    1 在下面路径下载 eclipse-jee-neon-2-linux-gtk-x86_64.tar.gzhttp://eclipse.stu.edu.tw/technology/epp/downloa ...

  10. hive学习5(复制表结构)

    hive复制表结构 CREATE TABLE new_table LIKE old_table; 例:创建一个和stg_job表一样表结构的s_job表 create table s_job like ...