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 ...
随机推荐
- C#中时间的Ticks属性
C#中时间的Ticks属性是一个很大的长整数,单位是 100 毫微秒.表示自 0001 年 1 月 1 日午夜 12:00:00 以来已经过的时间的以 100 毫微秒为间隔的间隔数,已经说得很清楚了, ...
- iOS WKWebView OC 与 JS 交互学习
我写WKWebView 想让 服务端相应 一个 方法但是不响应,根据 UIWebView 用 JSContext就能拿到响应的处理经验是不是服务端 也需要 对 WKwebView有兼容的一个写法??? ...
- $《第一行代码:Android》读书笔记——第5章 Broadcast
(一)广播机制简介 1.Android广播的分类: 如图所示: 2.发送广播:使用Intent:接收广播:Broadcast Receiver. (二)接收系统广播 1.动态注册监听网络变化 示例程序 ...
- 用matlab将nc数据读出来,写成二进制文件,然后用grads画图
clear,clc nt=735;ny=73; %2.5*2.5格点的nx=144; %2.5*2.5格点的f=netcdf('air.mon.mean.nc','nowrite');tt ...
- Laravel 调试利器 —— Laravel Debugbar 扩展包安装及使用教程
1.简介 Laravel Debugbar 在 Laravel 5 中集成了 PHP Debug Bar ,用于显示调试及错误信息以方便开发.该扩展包包含了一个 ServiceProvider 用于注 ...
- [POI2009]Wie
题目 BZOJ 虽然是解压题但也学到了简洁的码风 做法 \(dijkstra\)跑动规 My complete code #include<bits/stdc++.h> #include& ...
- iOS 学习之 UITabBarController
- (IBAction)btnClick:(id)sender { UITabBarController *tabBarCtrl = [[[UITabBarController alloc] init ...
- mongoDB中批量修改字段
// 为每一个文章文档新增一个image_count字段,用于记录此文章包含的图片个数 db['test.articles'].find({'title':'wfc test'}).forEach( ...
- Java中的UDP协议编程
一. UDP协议定义 UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层,处于IP协议的上一层.UDP有不提供数据报分组.组装和不能对数据包 ...
- Spark Shuffle的技术演进
在Spark或Hadoop MapReduce的分布式计算框架中,数据被按照key分成一块一块的分区,打散分布在集群中各个节点的物理存储或内存空间中,每个计算任务一次处理一个分区,但map端和re ...