洛谷P4116 Qtree3
题目描述
给出\(N\)个点的一棵树(\(N-1\)条边),节点有白有黑,初始全为白
有两种操作:
\(0\) \(i\) : 改变某点的颜色(原来是黑的变白,原来是白的变黑)
\(1\) \(v\) : 询问\(1\)到\(v\)的路径上的第一个黑点,若无,输出\(-1\)
输入输出格式
输入格式:
第一行 \(N\),\(Q\),表示\(N\)个点和\(Q\)个操作
第二行到第\(N\)行\(N-1\)条无向边
再之后\(Q\)行,每行一个操作"\(0\) \(i\)" 或者"\(1\) \(v\)" \((1 ≤ i, v ≤ N)\).
输出格式:
对每个\(1\) \(v\)操作输出结果
输入输出样例
输入样例#1:
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
输出样例#1:
-1
8
-1
2
-1
说明
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\).
思路:对于操作\(1\),显然我们可以利用线段树的单点修改操作来实现,对于操作\(2\),要求求\(1\)到\(v\)的路径上的第一个黑点,那么我们可以考虑维护两点之间路径之间是黑点的点的深度最浅值,可以用树链剖分+线段树来实现。
代码:
#include<cstdio>
#include<algorithm>
#include<cctype>
#define maxn 100007
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int inf=1e9+7;
int n,m,num,top[maxn],cnt,head[maxn],d[maxn],size[maxn],id[maxn];
int minn[maxn<<2],fa[maxn],son[maxn],a[maxn],w[maxn];
inline int qread() {
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';
return num*f;
}
struct node {
int v,nxt;
}e[maxn<<1];
inline void ct(int u, int v) {
e[++num].v=v;
e[num].nxt=head[u];
head[u]=num;
}
void dfs1(int u) {
size[u]=1;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v!=fa[u]) {
d[v]=d[u]+1;
fa[v]=u;
dfs1(v);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
}
void dfs2(int u, int t) {
id[u]=++cnt;
top[u]=t;
a[cnt]=u;
if(son[u]) dfs2(son[u],t);
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
inline void pushup(int rt) {
minn[rt]=min(minn[ls],minn[rs]);
}
void build(int rt, int l, int r) {
if(l==r) {
minn[rt]=inf;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(rt);
}
void modify(int rt, int l, int r, int L) {
if(l==r) {
if(w[id[L]]^=1) minn[rt]=l;
else minn[rt]=inf;
return;
}
int mid=(l+r)>>1;
if(L<=mid) modify(ls,l,mid,L);
else modify(rs,mid+1,r,L);
pushup(rt);
}
int cmin(int rt, int l, int r, int L, int R) {
if(L>r||R<l) return inf;
if(L<=l&&r<=R) return minn[rt];
int mid=(l+r)>>1,ans=inf;
if(L<=mid) ans=min(ans,cmin(ls,l,mid,L,R));
if(R>mid) ans=min(ans,cmin(rs,mid+1,r,L,R));
return ans;
}
int query(int x, int y) {
int fx=top[x],fy=top[y],ans=inf;
while(fx!=fy) {
if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
ans=min(ans,cmin(1,1,cnt,id[fx],id[x]));
x=fa[fx],fx=top[x];
}
if(id[x]>id[y]) swap(x,y);
ans=min(ans,cmin(1,1,cnt,id[x],id[y]));
return ans;
}
int main() {
n=qread(),m=qread();
for(int i=1,u,v;i<n;++i) {
u=qread(),v=qread();
ct(u,v);ct(v,u);
}
dfs1(1);dfs2(1,1);build(1,1,n);
for(int i=1,k,x;i<=m;++i) {
k=qread(),x=qread();
if(!k) modify(1,1,n,id[x]);
else {
int zrj=query(1,x);
if(zrj==inf) printf("-1\n");
else printf("%d\n",a[zrj]);
}
}
return 0;
}
洛谷P4116 Qtree3的更多相关文章
- 洛谷 P4116 Qtree3
Qtree系列第三题 我是题面 读完题大概不难判断是一道树剖的题 这道题的关键是记录两种状态,以及黑点的序号(不是编号) 线段树啊当然 定义两个变量v,f,v表示距离根节点最近的黑点,默认-1,f则表 ...
- 洛谷P4116 Qtree3(树剖+线段树)
传送门 LCT秒天秒地 树剖比较裸的题了 用线段树记录一下区间的最左边的黑点的编号(因为同一条链上肯定是最左边的深度最小,到根节点距离最近) 然后记得树剖的时候肯定是越后面的答案越优,因为深度越浅 / ...
- 【洛谷 P4116】 Qtree3 (树链剖分)
题目链接 树剖练手题,想复习下树剖. 第一次提交\(T\)成QQC 看我 ??? 看了数据范围的确挺恶心的,我的复杂度是\(O(Mlog^2N)\)的,数据范围有三段 For 1/3 of the t ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
随机推荐
- codeforces 632A A. Grandma Laura and Apples(暴力)
A. Grandma Laura and Apples time limit per test 1 second memory limit per test 256 megabytes input s ...
- poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
- java多线程编程核心技术——第一章总结
目录: 1.1进程.多线程的概念,及线程的优点 1.2多线程的使用 1.3currentThread()方法 1.4isAlive()方法 1.5sleep()方法 1.6getId()方法 1.7停 ...
- 关系运算符 逻辑运算符 if 语句 switch语句
1. BOOL类型 BOOL isRightOrNo = YES; isRightOrNo = 56;//可以打印出来,在C语言中,非0即真 printf("%d\n" , isR ...
- 如何调整chm文字字体大小
chm文档是使用用层叠样式表来控制字符大小的,通过IE的改变“文字大小”是没效果的,那我们是不是就没有办法改变它的大小了呢?显然不是的. 工具/原料 chm文件 方法/步骤 首先打开chm ...
- VisualGDB系列7:使用VS创建Linux静态库和动态库
根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何在VS中创建静态库和动态库, ...
- mybatis 学习三 mapper xml 配置信息
mapper xml 映射文件 1,select 标签 简单是用就这样,其中resultType 代表从这条语句中返回的期望类型的类的完全限定名或别名.也可以使用resultMap对应的id ...
- js中Function方法
function.apply(thisArg,argArray) apply方法调用function,传递一个会绑定到this上的对象和一个可选的数组作为参数. apply方法被用在apply调用模式 ...
- elasticsearch2.x插件之一:kibana
介绍: 要说kibana,就不得不先说一下logstash.这里呢,先要讲个故事.故事是开头是这样的,Logstash早期曾经自带了一个特别简单的logstash-web用来查看ES中的数据,其功能太 ...
- 向PCD文件写入点云数据
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=83 本小节我们学习如何向PCD文件写入点云数据. 代码 章例2文件夹中,打开 ...