SP10707 COT2 - Count on a tree II 莫队
链接
https://vjudge.net/problem/SPOJ-COT2
https://www.luogu.org/problemnew/show/SP10707
思路
dfs欧拉序转化为普通莫队(并不算树上莫队,不过也可做)
好神仙啊,原来欧拉序是可以求任意两点的点,不过要加lca。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,w[N],now_ans,top;
vector<int> G[N];
int st[N][30],dep[N],belong[N<<1],ans[N];
int lsh[N],a[N<<1],be[N],en[N<<1],T[N];
int js[N];
struct node {
int l,r,other,id;
bool operator < (const node &b) const {
return belong[l]==belong[b.l] ? belong[l]&1 ? r<b.r : r>b.r :belong[l]<belong[b.l];
}
}Q[N];
void dfs(int u,int f) {
a[++top]=u;
be[u]=top;
for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) {
if(*it==f) continue;
st[*it][0]=u;
dep[*it]=dep[u]+1;
dfs(*it,u);
}
a[++top]=u;
en[u]=top;
}
int lca(int x,int y) {
if(dep[x]<dep[y]) swap(x,y);
for(int i=25;i>=0;--i)
if(dep[st[x][i]]>=dep[y]) x=st[x][i];
if(x==y) return x;
for(int i=25;i>=0;--i)
if(st[x][i]!=st[y][i]) x=st[x][i],y=st[y][i];
return st[x][0];
}
void add(int x) {
if(!T[x]) now_ans++;
T[x]++;
}
void del(int x) {
T[x]--;
if(!T[x]) now_ans--;
}
int main() {
//freopen("a.in","r",stdin);
n=read(),m=read();
for(int i=1;i<=n;++i) lsh[i]=w[i]=read();
sort(lsh+1,lsh+1+n);
int len=unique(lsh+1,lsh+1+n)-lsh-1;
for(int i=1;i<=n;++i) w[i]=lower_bound(lsh+1,lsh+1+len,w[i])-lsh;
for(int i=1;i<n;++i) {
int x=read(),y=read();
G[x].push_back(y);
G[y].push_back(x);
}
dep[1]=1;
dfs(1,0);
for(int j=1;j<=25;++j) {
for(int i=1;i<=n;++i) {
st[i][j]=st[st[i][j-1]][j-1];
}
}
for(int i=1;i<=m;++i) {
int x=read(),y=read(),z=lca(x,y);
if(be[x]>be[y]) swap(x,y);
if(z==x||z==y) {
Q[i].l=be[x];
Q[i].r=be[y];
Q[i].other=0;
} else {
Q[i].l=en[x];
Q[i].r=be[y];
Q[i].other=z;
}
Q[i].id=i;
}
int k=sqrt(2*n);
for(int i=1;i<=2*n;++i) belong[i]=(i-1)/k+1;
sort(Q+1,Q+1+m);
for(int i=1,l=1,r=0;i<=m;++i) {
while(r<Q[i].r) {//add(++r)
++r;
if(js[a[r]])
del(w[a[r]]);
else
add(w[a[r]]);
js[a[r]]^=1;
}
while(l>Q[i].l) {//add(--l)
--l;
if(js[a[l]])
del(w[a[l]]);
else
add(w[a[l]]);
js[a[l]]^=1;
}
while(l<Q[i].l) {//del(l++)
if(js[a[l]])
del(w[a[l]]);
else
add(w[a[l]]);
js[a[l]]^=1;
l++;
}
while(r>Q[i].r) {//del(r--)
if(js[a[r]])
del(w[a[r]]);
else
add(w[a[r]]);
js[a[r]]^=1;
r--;
}
if(Q[i].other)
add(w[Q[i].other]);
ans[Q[i].id]=now_ans;
if(Q[i].other)
del(w[Q[i].other]);
// cout<<Q[i].l<<" "<<Q[i].r<<"\n";
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;
}
SP10707 COT2 - Count on a tree II 莫队的更多相关文章
- SP10707 COT2 - Count on a tree II 莫队上树
题意:求一条链 \((u,v)\) 上不同的颜色数. 我们可以求出树的出栈入栈序(or 括号序?我也不确定). 图(from attack) 然后有一个很优美的性质: 设点 \(u\) 的入栈时间为 ...
- SP10707 COT2 - Count on a tree II (树上莫队)
大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...
- SP10707 COT2 - Count on a tree II [树上莫队学习笔记]
树上莫队就是把莫队搬到树上-利用欧拉序乱搞.. 子树自然是普通莫队轻松解决了 链上的话 只能用树上莫队了吧.. 考虑多种情况 [X=LCA(X,Y)] [Y=LCA(X,Y)] else void d ...
- [SP10707]COT2 - Count on a tree II
题目大意:有一棵$n$个节点的树,第$i$个点有一个颜色$C_i$,$m$组询问,每次问$x->y$的路径上有多少种颜色 题解:树上莫队,把树按欧拉序展开成一条链,令第$i$个节点第一次出现在序 ...
- 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 ...
- 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 ...
- 【SPOJ10707】 COT2 Count on a tree II
SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...
- 【树上莫队】【SP10707】 COT2 - Count on a tree II
Description 给定一棵 \(n\) 个点的树,每个节点有一个权值,\(m\) 次询问,每次查询两点间路径上有多少不同的权值 Input 第一行是 \(n\) 和 \(m\) 第二行是 \(n ...
随机推荐
- java 控制台输入
import java . util . Scanner ; public class Test { public static void main(String[] args) { Scanner ...
- 关于django编码问题所导致的502错误
在使用django开发的时候,访问网站出现了502错误,次数也比较平繁 uwsgi+nginx+django 在命令行下提示如下错误 : File "/opt/apps/python3/li ...
- 【2017-04-20】Sql字符串注入式攻击与防御,实体类,数据访问类
字符串攻击 所谓sql字符串注入式攻击就是在用户输入界面输入通过精心编制的含有某种指令的字符串,来改变C#中连接数据库要执行的sql语句,从而对数据库进行攻击性操作 在用户输入界面输入 a');up ...
- 1.python虚拟环境的安装-用以同时使用py2,py3
第一步:安装环境支持[linux下在前加sudo] http://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl pip install virtualenv 第 ...
- Spring源码阅读(四)
我们知道,在spring bean生命周期中,我们可以在不同阶段执行处理器或者方法,比如init-method,destroy方法,BeanPostProcessor接口等.那么这些处理器或方法的执行 ...
- 20165305 苏振龙《Java程序设计》第一周学习总结
20165305 <Java程序设计>第一周学习总结 教材学习内容总结 我重点学习了jdk安装后面的第一章内容,算是更进一步的的了解了一些Java方面的基础知识. Java平台概论 Jav ...
- 如何删除自己上传的CSDN资源(亲测有效)
今天发现有一个资源上传错了,想重新上传,删掉以前的资源,才发现CSDN并没有提供删除资源的功能,然后去网上搜了下,这才删除了,不知道怎么删除的小伙伴看过来~ 1.首先,找到自己想要删除资源的页面,举个 ...
- mybatis源码解析2---SqlSessionFactoryBuilder、SqlSessionFactory解析
1.先看一个mybatis最简单的Demo String resource = "mybatis-config.xml"; //1.流形式读取mybatis配置文件 InputSt ...
- 复习loadRunner参数化
参数化: 为什么要用参数化? 如果是单一数据,那么会纯测试缓存. 如果是参数化,基本上大部分数据不会被缓存命中. 极端情况:所有的数据都不会被缓存命中,或者少量命中. 在loadrunner中,所有的 ...
- linux下can调试工具canutils安装过程记录
https://www.cnblogs.com/chenfulin5/p/6797756.html 一.下载源码 下载canutils和libsocketcan libsocketcan地址:http ...