SPOJ QTREE3 - Query on a tree again!
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N. In the start, the color of any node in the tree is white.
We will ask you to perfrom some instructions of the following form:
- 0 i : change the color of the i-th node (from white to black, or from black to white);
or - 1 v : ask for the id of the first black node on the path from node 1 to node v. if it doesn't exist, you may return -1 as its result.
Input
In the first line there are two integers N and Q.
In the next N-1 lines describe the edges in the tree: a line with two integers a b denotes an edge between a and b.
The next Q lines contain instructions "0 i" or "1 v" (1 ≤ i, v ≤ N).
Output
For each "1 v" operation, write one integer representing its result.
Example
Input:
9 8
1 2
1 3
2 4
2 9
5 9
7 9
8 9
6 8
1 3
0 8
1 6
1 7
0 2
1 9
0 2
1 9 Output:
-1
8
-1
2
-1
Constraints & Limits
There are 12 real input files.
For 1/3 of the test cases, N=5000, Q=400000.
For 1/3 of the test cases, N=10000, Q=300000.
For 1/3 of the test cases, N=100000, Q=100000.
一棵树,点数<=100000,初始全是白点,支持两种操作:
1.将某个点的颜色反色。
2.询问某个点至根节点路径上第一个黑点是哪个。
树链剖分
注意到询问的链都是(1,v)
在线段树上维护区间内深度最浅的黑色点位置即可,注意线段树结点到原树的反向映射
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int INF=1e9;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*-''+ch;ch=getchar();}
return x*f;
}
struct edge{int v,nxt;}e[mxn<<];
int hd[mxn],mct=;
int n,q;
void add_edge(int u,int v){
e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
}
struct node{
int fa,son;
int top,size;
int w;
}t[mxn];
int sz=;
int dep[mxn];
int id[mxn];
void DFS1(int u,int fa){
dep[u]=dep[fa]+;
t[u].size=;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;if(v==fa)continue;
t[v].fa=u;
DFS1(v,u);
t[u].size+=t[v].size;
if(t[v].size>t[t[u].son].size)
t[u].son=v;
}
return;
}
void DFS2(int u,int top){
t[u].w=++sz;t[u].top=top;
id[sz]=u;
if(t[u].son)DFS2(t[u].son,top);
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==t[u].fa || v==t[u].son)continue;
DFS2(v,v);
}
return;
}
struct SGT{
int ps;
int c;
}st[mxn<<];
void Build(int l,int r,int rt){
st[rt].ps=INF;
if(l==r)return;
int mid=(l+r)>>;
Build(l,mid,rt<<);Build(mid+,r,rt<<|);
return;
}
void update(int p,int l,int r,int rt){
if(l==r){
st[rt].c^=;
st[rt].ps=(st[rt].c)?l:INF;
return;
}
int mid=(l+r)>>;
if(p<=mid)update(p,l,mid,rt<<);
else update(p,mid+,r,rt<<|);
st[rt].ps=min(st[rt<<].ps,st[rt<<|].ps);
return;
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R){return st[rt].ps;}
int mid=(l+r)>>;
int res=INF;
if(L<=mid)res=min(res,query(L,R,l,mid,rt<<));
if(R>mid && res>mid)res=min(res,query(L,R,mid+,r,rt<<|));
return res;
}
int Qt(int x,int y){
int res=INF;
while(t[x].top!=t[y].top){
if(dep[t[x].top]<dep[t[y].top])swap(x,y);
res=min(res,query(t[t[x].top].w,t[x].w,,n,));
x=t[t[x].top].fa;
}
if(dep[x]>dep[y])swap(x,y);
res=min(res,query(t[x].w,t[y].w,,n,));
return res;
}
int main(){
int i,j,u,v;
n=read();q=read();
for(i=;i<n;i++){
u=read();v=read();
add_edge(u,v);
add_edge(v,u);
}
DFS1(,);
DFS2(,);
Build(,n,);
while(q--){
u=read();v=read();
if(!u)
update(t[v].w,,n,);
else{
int ans=Qt(,v);
if(ans>=INF){printf("-1\n");continue;}
ans=id[ans];
printf("%d\n",ans);
}
}
return ;
}
SPOJ QTREE3 - Query on a tree again!的更多相关文章
- SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree
[题目分析] QTREE2,一看是倍增算法,太懒了,不写了.( ̄_, ̄ ) QTREE3,树链剖分可以做,发现链上的问题LCT也很好做. 要是子树问题貌似可以DFS序. 然后就成LCT模板题了. 考前 ...
- QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树
Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...
- SPOJ 375. Query on a tree (树链剖分)
Query on a tree Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Ori ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- spoj 375 Query on a tree(树链剖分,线段树)
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Sub ...
- 动态树(Link Cut Tree) :SPOJ 375 Query on a tree
QTREE - Query on a tree #number-theory You are given a tree (an acyclic undirected connected graph) ...
- SPOJ 375. Query on a tree (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- SPOJ PT07J - Query on a tree III(划分树)
PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...
- spoj 913 Query on a tree II (倍增lca)
Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...
随机推荐
- 从 Objective-C 里的 Alloc 和 AllocWithZone 谈起
一.问题起源 一切起源于Apple官方文档里面关于单例(Singleton)的示范代码:Creating a Singleton Instance.主要的争议集中在下面这一段: static MyGi ...
- ReactiveCocoa入门-part2
ReactiveCocoa是一个框架,它能让你在iOS应用中使用函数响应式编程(FRP)技术.在本系列教程的第一部分中,你学到了如何将标准的动作与事件处理逻辑替换为发送事件流的信号.你还学到了如何转换 ...
- React组件自适应窗口宽高
很多时候我们需要组件能够根据窗口变化改变宽高,有时候可以使用css,有时候需要随数据调整则使用js计算. 比如说,当我们在页面中放置一个iframe时,我们希望它的宽高随着其父元素or窗口的变化而变化 ...
- 初探es6
es6环境 现在的JavaScript 引擎还不能完全支持es6的新语法.新特性.所以要想在页面中直接使用,是会报错的,这时候就需要使用babel将es2015的特性转换为ES5 标准的代码. 1.全 ...
- mysql 主从数据校验
使用工具pt-table-checksum: /usr/bin/pt-table-checksum --user=root --password='mysqlpass' --host=127.0.0. ...
- Docker 镜像&仓库 获取及推送镜像
docker查看.删除镜像 docker镜像存储位置: /var/lib/docker 查看docker信息也可以查看保存位置 docker info 1.列出镜像 docker images -aa ...
- 标准C++(1)
一.引用 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符 &引用名=目标变量名: 例: int& num; 引用类似于起别名 注 ...
- 命令行下创建MySQL数据库与创建用户以及授权
先以root用户登录mysql: C:\Users\XXX>mysql -u root -p 输入密码后登录,接下来操作如下: 1.创建数据库 语法:create schema [数据库名称] ...
- 【php】对象的比较
对象的比较 相等的比较 ==当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等. 全等的比较 ===如果 ...
- Python9-loggin模块-day29
什么叫日志日志 是用来记录用户行为或者代码的执行过程 # import logging # logging.debug('debug message') #低级别的 排除信息 # logging.in ...