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常用模块——random模块
参考博客:http://www.360doc.com/content/14/0430/11/16044571_373443266.shtml 今天突然想起python该怎么生成随机数?查了一下,贴出实 ...
- webbrowser控件——Windows下的开发利器
首先说明,本人比较菜,做C++没多长时间. 刚开始用MFC写程序时,连个基本的字体都不会变(颜色.大小等), 索性干脆就啥也不改了,直接默认,界面就那样了,老子不管了. 心想这C++做个界面咋就那么麻 ...
- 容器排序之sort,stable_sort
bool isShorter(const string &s1, const string &sz){ return s1.size() < sz.size(); } int m ...
- CSS伪元素实现的3D按钮
在线演示 本地下载
- samtools使用过程中出现的问题
1.EOP marker is absent 在使用samtools index时出现 EOF是指the end of file,即samtools认为你的bam文件是不完整的. 如果把view参数的 ...
- 20145239杜文超《网络对抗》- shellcode注入&Return-to-libc攻击深入
20145239杜文超<网络对抗>- shellcode注入&Return-to-libc攻击深入 shellcode基础知识 Shellcode是一段代码,作为数据发送给受攻击服 ...
- Android SDK组件:webview笔记
1.安卓手机中内置了一款webkit内核的浏览器,在SDK中封装为WebView组件. 2.该组件可以在自己的应用程序中显示本地或者Internet上的网页,也可以把它当作一个浏览器来时用. 3.We ...
- 实现利用公钥私钥免密码登录Linux服务器
原理 客户端生成公钥私钥,把公钥拷贝给linux服务器,用自己的私钥连接服务器.实现如下: 如果是两台Linux服用器A和B,A来实现免密码登录B A执行ssh-keygen -t rsa 就会在/r ...
- oracle 启动数据库与监听器
1.oracle 启动数据库与监听器 1)启动数据库 oracle用户进去 oracle/oracle sqlplus / as sysdba 然后startup 退出,然后启动监听进程 2)启动监听 ...
- Luogu-4022 [CTSC2012]熟悉的文章
广义后缀自动机+DP 对于作文库建出广义后缀自动机,广义自动机就是在每次添加一个字符串之前把\(last=0\),然后正常添加就好了 对于每个询问串,预处理出每个位置\(i\)能向前匹配的最长长度\( ...