SPOJ 10707 COT2 - Count on a tree II
思路
树上莫队的题目
每次更新(u1,u2)和(v1,v2)(不包括lca)的路径,最后单独统计LCA即可
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std;
int v[100100*2],fir[100100],nxt[100100*2],cnt=0,w_p[100100],b[100100],n,m,tx,sum,jump[100100][20],dep[100100],in_ans[100100],sz,belong[100100],block_cnt,ans[100100],color[100100],U,V;
stack<int> S;
void addedge(int ui,int vi){
++cnt;
v[cnt]=vi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
void dfs(int u,int f){
jump[u][0]=f;
for(int i=1;i<20;i++)
jump[u][i]=jump[jump[u][i-1]][i-1];
dep[u]=dep[f]+1;
int t=S.size();
for(int i=fir[u];i;i=nxt[i]){
if(v[i]==f)
continue;
dfs(v[i],u);
if(S.size()-t>=sz){
++block_cnt;
while(S.size()>t){
belong[S.top()]=block_cnt;
S.pop();
}
}
}
S.push(u);
}
void init(void){
sz=sqrt(n);
dfs(1,0);
}
int lca(int x,int y){
if(dep[x]<dep[y])
swap(x,y);
for(int i=19;i>=0;i--)
if(dep[jump[x][i]]>=dep[y])
x=jump[x][i];
if(x==y)
return x;
for(int i=19;i>=0;i--)
if(jump[x][i]!=jump[y][i])
x=jump[x][i],y=jump[y][i];
return jump[x][0];
}
void modi_point(int x){
if(in_ans[x]){//erase
color[w_p[x]]--;
if(!color[w_p[x]])
sum--;
}
else{
if(!color[w_p[x]])
sum++;
color[w_p[x]]++;
}
in_ans[x]^=1;
}
void move_path(int x,int y){//(x,y) except LCA(x,y)
if(dep[x]<dep[y])
swap(x,y);
while(dep[x]>dep[y]){
modi_point(x);
x=jump[x][0];
}
while(x!=y){
modi_point(x);
modi_point(y);
x=jump[x][0];
y=jump[y][0];
}
}
struct Query{
int u,v,id;
bool operator < (const Query &b) const{
return (belong[u]==belong[b.u])?belong[v]<belong[b.v]:belong[u]<belong[b.u];
}
}Q[100100];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&w_p[i]),b[i]=w_p[i];
sort(b+1,b+n+1);
tx=unique(b+1,b+n+1)-(b+1);
for(int i=1;i<=n;i++)
w_p[i]=lower_bound(b+1,b+n+1,w_p[i])-b;
for(int i=1;i<n;i++){
int a,b;
scanf("%d %d",&a,&b);
addedge(a,b);
addedge(b,a);
}
init();
for(int i=1;i<=m;i++){
scanf("%d %d",&Q[i].u,&Q[i].v);
Q[i].id=i;
}
sort(Q+1,Q+m+1);
U=V=1;
for(int i=1;i<=m;i++){
move_path(U,Q[i].u);
move_path(V,Q[i].v);
U=Q[i].u;
V=Q[i].v;
int Lca=lca(Q[i].u,Q[i].v);
modi_point(Lca);
ans[Q[i].id]=sum;
modi_point(Lca);
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}
SPOJ 10707 COT2 - Count on a tree II的更多相关文章
- bzoj2589【 Spoj 10707】 Count on a tree II
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor lastans和v这两个节点间有多少种不同的点权.其中lastans是上一个询问的答案,初始为0,即第一 ...
- SPOJ:COT2 Count on a tree II
题意 给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数. n=40000,m=100000 Sol 树上莫队模板题 # include <bits/stdc++.h ...
- 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(LCA+离散化+树上莫队)
COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from ...
- 【SPOJ10707】 COT2 Count on a tree II
SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...
- 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(树上莫队)
题目链接: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 (树上莫队)
题目链接:http://www.spoj.com/problems/COT2/ 参考博客:http://www.cnblogs.com/xcw0754/p/4763804.html上面这个人推导部分写 ...
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
随机推荐
- rqnoj PID95:多多看DVD(加强版)
题目描述 多多进幼儿园了,今天报名了.只有今晚可以好好放松一下了(以后上了学后会很忙).她的叔叔决定给他买一些动画片DVD晚上看.可是爷爷规定他们只能在一定的时间段L看完.(因为叔叔还要搞NOIP不能 ...
- 【AI】【人工智能】【计算机】人工智能工程技术人员等职业信息公示
人社厅发[2019]48号 各省.自治区.直辖市及新疆生产建设兵团人力资源社会保障厅(局).市场监管局.统计局,国务院各部门.各直属机构.各中央企业.有关社会组织人事劳动保障工作机构,中央军委政治工作 ...
- *#【Python】【基础知识】【模块】【datetime】【使用datetime模块 】
datetime模块 的介绍: 用于调取时间.日期 datetime包含的 方法: >>> dir(datetime) ['MAXYEAR', 'MINYEAR', '__built ...
- HanLP-地名识别调试方法
HanLP收词特别是实体比较多,因此特别容易造成误识别.下边举几个地名误识别的例子,需要指出的是,后边的机构名识别也以地名识别为基础,因此,如果地名识别不准确,也会导致机构名识别不准确. 类型1 数字 ...
- nginx+uwsgi02---django部署(推荐)
参考 https://blog.csdn.net/weixin_39198406/article/details/79277580 https://www.cnblogs.com/alex3714/ ...
- 如何查看class文件的编译jdk版本号
使用命令 javap -verbose 命 进入cmd中,使用如下命令 红色
- 1.3.4 Fork/Join框架
package com.study.forkjoin; import java.util.ArrayList; import java.util.List; import java.util.conc ...
- # localhost 、217.0.0.1 、本机IP
localhost .217.0.0.1 .本机IP localhost是一个域名,性质跟 "www.baidu.com" 差不多,指向127.0.0.1这个IP地址,在windo ...
- 怎样通过name属性获取元素节点集合
使用 document.getElementsByName(); document.getElementsByName("userInfo") instanceof NodeLis ...
- 使用Visual Studio2019 开启Openmp的方法
调试-->属性-->C/C++-->所有选项-->Openmp支持改为 是(可以使用下拉菜单) 严重性 代码 说明 项目 文件 行 禁止显示状态 禁止显示状态 错误 C2338 ...