Count On A Tree II.
$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.的更多相关文章
- 【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 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...
- 【BZOJ2589】[SPOJ10707]Count on a tree II
[BZOJ2589][SPOJ10707]Count on a tree II 题面 bzoj 题解 这题如果不强制在线就是一个很\(sb\)的莫队了,但是它强制在线啊\(qaq\) 所以我们就用到了 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- 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 ...
- AC日记——Count on a tree II spoj
Count on a tree II 思路: 树上莫队: 先分块,然后,就好办了: 来,上代码: #include <cmath> #include <cstdio> #inc ...
- 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 ...
- 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 ...
- 「SPOJ10707」Count on a tree II
「SPOJ10707」Count on a tree II 传送门 树上莫队板子题. 锻炼基础,没什么好说的. 参考代码: #include <algorithm> #include &l ...
- 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 ...
随机推荐
- Python函数之—— 装饰器(Day13)
一.什么是装饰器 顾名思义,装饰器指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 二.装饰器需要遵循的原则 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数 ...
- val() attr('value')
val() 只能更改输入框内的值,能更改value属性, 在浏览器中体现不出value被改变 attr('value') 都可以 谷歌浏览器 val,attr都能获取输入框最新的value值
- Python3 进程 线程 同步锁 线程死锁和递归锁
进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...
- asp.net IRequiresSessionState
在一般处理程序中,使用context.Session对象,必须先继承IRequiresSessionState接口. System.Web.SessionState.IRequiresSessionS ...
- c# 抽象类(abstract)
using System; using System.Collections.Generic; using System.Linq; using System.Text; //抽象类(abstract ...
- UI控件之UINavigationController
ViewController1 *vc1=[[ViewController1 alloc]init]; UINavigationController *nav1=[[UINavigationContr ...
- pdo封装2
<?php //添加了一个 _createSql 方法,负责创建所有sql class Db{ static private $ins; private $pdo; private $table ...
- 主攻ASP.NET.4.5.1 MVC5.0之重生:根据产品类别显示菜单分类和分页
路径访问的几种方式和分页效果 显示其它类别的效果和多数据分页效果 默认访问网站路径效果和多数据分页效果 URL路径访问可页面 http://localhost:5339/stationery http ...
- js实现给一个数组监听
$.when.apply(null, table).done(callback); table=[]是个数组,用上$.when.apply就可以监听完成后执行callback 方法 callback就 ...
- 在.h和.cpp中包含头文件的区别
1.在.h中包含头文件,是为了声明一系列这个头文件的变量等,可能会产生重复包含的问题: 2.在.cpp中包含头文件只是为了实现这个头文件或者使用其中的方法,不会有重复包含的问题,所以尽量在源文件中包含 ...