[SPOJ]COT2
题意:给一棵带点权的树,多次询问两点间路径上的不同权值数
学习了一下莫队上树(雾
先求出栈入栈序$p_{1\cdots 2n}$,记$st_x$为$x$在$p$中第一次出现的位置,$ed_x$为$x$在$p$中最后一次出现的位置
对于一个询问$(x,y)$,先令$st_x\lt st_y$,求出其$lca$,若$x=lca$,则询问$[st_x,st_y]$,否则询问$[ed_x,st_y]$还有$lca$(因为$[ed_x,st_y]$不包含$lca$)
于是我们成功地把问题转化到序列上,普通地莫队即可
不应处理出现两次的数(因为它入栈一次,出栈一次,在路径之外)
#include<stdio.h>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
struct ask{
int l,r,lca,sid,qid;
}q[100010];
int to[80010],nex[80010],h[40010],dep[40010],fa[40010][16],v[40010],p[80010],st[40010],ed[40010],ti[40010],ex[40010],ans[100010],M;
map<int,int>mp;
map<int,int>::iterator it;
bool cmp(ask a,ask b){
if(a.sid==b.sid)return a.r<b.r;
return a.sid<b.sid;
}
void add(int a,int b){
M++;
to[M]=b;
nex[M]=h[a];
h[a]=M;
}
void dfs(int x){
st[x]=++M;
p[M]=x;
for(int i=h[x];i;i=nex[i]){
if(to[i]!=fa[x][0]){
fa[to[i]][0]=x;
dep[to[i]]=dep[x]+1;
dfs(to[i]);
}
}
ed[x]=++M;
p[M]=x;
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int i;
for(i=15;i>=0;i--){
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
}
if(x==y)return x;
for(i=15;i>=0;i--){
if(fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
int sum;
void add(int);
void del(int x){
if(ex[x]==0)return add(x);
ti[v[x]]--;
if(ti[v[x]]==0)sum--;
ex[x]=0;
}
void add(int x){
if(ex[x])return del(x);
if(ti[v[x]]==0)sum++;
ti[v[x]]++;
ex[x]=1;
}
int main(){
int n,m,i,j,x,y,l,r,sq;
scanf("%d%d",&n,&m);
sq=sqrt(n);
for(i=1;i<=n;i++){
scanf("%d",v+i);
mp[v[i]]=1;
}
for(i=1,it=mp.begin();it!=mp.end();it++,i++)it->second=i;
for(i=1;i<=n;i++)v[i]=mp[v[i]];
for(i=1;i<n;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
M=0;
dep[1]=1;
dfs(1);
for(j=1;j<16;j++){
for(i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];
}
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
if(st[x]>st[y])swap(x,y);
j=lca(x,y);
q[i].r=st[y];
if(x==j)
q[i].l=st[x];
else{
q[i].l=ed[x];
q[i].lca=j;
}
q[i].sid=q[i].l/sq;
q[i].qid=i;
}
sort(q+1,q+m+1,cmp);
l=r=1;
add(1);
for(i=1;i<=m;i++){
while(l>q[i].l){
l--;
add(p[l]);
}
while(r<q[i].r){
r++;
add(p[r]);
}
while(l<q[i].l){
del(p[l]);
l++;
}
while(r>q[i].r){
del(p[r]);
r--;
}
if(q[i].lca)add(q[i].lca);
ans[q[i].qid]=sum;
if(q[i].lca)del(q[i].lca);
}
for(i=1;i<=m;i++)printf("%d\n",ans[i]);
}
[SPOJ]COT2的更多相关文章
- 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 ...
- 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 ...
- 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 ...
- SPOJ COT2 Count on a tree II (树上莫队)
题目链接:http://www.spoj.com/problems/COT2/ 参考博客:http://www.cnblogs.com/xcw0754/p/4763804.html上面这个人推导部分写 ...
- SPOJ COT2 树上找路径上不同值的个数
题目大意 给出多个询问u , v , 求出u-v路径上点权值不同的个数 开始做的是COT1,用主席树写过了,理解起来不难 很高兴的跑去做第二道,完全跟普通数组区间求k个不同有很大区别,完全没思路 膜拜 ...
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
- spoj COT2(树上莫队)
模板.树上莫队的分块就是按dfn分,然后区间之间转移时注意一下就好.有个图方便理解http://blog.csdn.net/thy_asdf/article/details/47377709: #in ...
- 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)
题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...
- SPOJ - COT2 离线路径统计
题意:求\(u\)到\(v\)的最短路径的不同权值种类个数 树上莫队试水题,这一篇是上篇的弱化部分,但可测试以下结论的正确性 设\(S(u,v)\):\(u-v\)最短路径所覆盖的点集 \(S(u,v ...
随机推荐
- cloudera manager 5.3完整卸载脚本
service cloudera-scm-agent stop service cloudera-scm-agent stop umount /var/run/cloudera-scm-agent/p ...
- JS alert()、confirm()、prompt()的区别
这三个都是属于弹框类型的 使用警告.提示和确认消息框来获得用户的输入.这些消息框是 window 对象的接口方法.由于 window 对象位于对象层次的顶层,因此实际应用中不必使用这些消息框的全名(例 ...
- es6+最佳入门实践(13)
13.模块化 13.1.什么是模块化 模块化是一种处理复杂系统分解为更好的可管理模块的方式.通俗的讲就是把一个复杂的功能拆分成多个小功能,并且以一种良好的机制管理起来,这样就可以认为是模块化.就像作家 ...
- es6+最佳入门实践(8)
8.Promise 8.1.什么是异步? 要理解异步,首先,从同步代码开始说 alert(1) alert(2) 像上面的代码,执行顺序是从上到下,先后弹出1和2,这种代码叫做同步代码 alert(0 ...
- cxf+spring发布webservice和调用
maven项目配置http://cxf.apache.org/docs/using-cxf-with-maven.html <properties> <cxf.version> ...
- 调整文本输入框placeholder的颜色等样式
input::-webkit-input-placeholder{ color: white !important;}input:-moz-placeholder{ color: whi ...
- Spring - IoC(4): p-namespace & c-namespace
p 命名空间 p 命名空间允许你使用 bean 元素的属性而不是 <property/>子元素来描述 Bean 实例的属性值.从 Spring2.0 开始,Spring 支持基于 XML ...
- 膨胀、腐蚀、开、闭(matlab实现)
膨胀.腐蚀.开.闭运算是数学形态学最基本的变换. 本文主要针对二值图像的形态学 膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔): B=[0 1 0 1 1 1 ...
- idea讲web项目部署到tomcat,热部署
idea是自动保存文件的,不需要ctrl+s手动保存. idea使用不习惯,修改了jsp文件后,刷新浏览器并没有立刻显示出来,而是要重新编译一下代码,重新部署才会出现. 在idea tomcat 中s ...
- Quartus ModelSim联合仿真中的RAM初始化
Modelsim只支持Hex格式的初始化文件,文件需要放在仿真的根目录下,例如:.\simulation\modelsim:并且在利用Quartus宏生成IP时,选择的初始化文件必须用绝对路径!否则M ...