题目描述

给出\(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的更多相关文章

  1. 洛谷 P4116 Qtree3

    Qtree系列第三题 我是题面 读完题大概不难判断是一道树剖的题 这道题的关键是记录两种状态,以及黑点的序号(不是编号) 线段树啊当然 定义两个变量v,f,v表示距离根节点最近的黑点,默认-1,f则表 ...

  2. 洛谷P4116 Qtree3(树剖+线段树)

    传送门 LCT秒天秒地 树剖比较裸的题了 用线段树记录一下区间的最左边的黑点的编号(因为同一条链上肯定是最左边的深度最小,到根节点距离最近) 然后记得树剖的时候肯定是越后面的答案越优,因为深度越浅 / ...

  3. 【洛谷 P4116】 Qtree3 (树链剖分)

    题目链接 树剖练手题,想复习下树剖. 第一次提交\(T\)成QQC 看我 ??? 看了数据范围的确挺恶心的,我的复杂度是\(O(Mlog^2N)\)的,数据范围有三段 For 1/3 of the t ...

  4. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  5. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  6. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  7. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  8. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  9. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

随机推荐

  1. Sqlite表结构读取工具,word批量转html,在线云剪贴板,文件批量提取工具;

    工欲善其事必先利其器,本周为您推荐工具排行 Sqlite表结构读取工具,word批量转html,在线云剪贴板,文件批量提取工具:     本周我们又要发干货了,准备好接受了吗? 为什么是干货,就是因为 ...

  2. [HDU5290]Bombing plan

    vjudge sol 树DP. 首先把模型转换成:每个点可以控制与它距离不超过\(w_i\)的点,先要求选出数量最少的点控制所有点. 设\(f[i][-100...100]\)表示\(i\)号点向上还 ...

  3. django models class 不识别问题解决方案

    目录 1. 事情起因 2. 排查经过 3. 总结 1. 事情起因 今天在写代码的时候,在django 的models目录中新增了一个pkg.py文件,里面定义了一个class, 在执行 makemig ...

  4. Core Data存储数据出错(This NSPersistentStoreCoordinator has no persistent stores (unknown))

    Core Data存储数据的时候崩溃,崩溃信息: reason: 'This NSPersistentStoreCoordinator has no persistent stores (unknow ...

  5. 自定义type为file型input控件+该控件具有本地图片预览功能

    最近的一个项目需求是写一个type为filex型的input控件,这个控件: 第一,要自定义样式: 第二,要能直接在本地预览上传的图片: 第三,要能检测图片的尺寸是否符合要求. 故综合网上的资源写了下 ...

  6. 动态webService

    using System; using System.Net; using System.IO; using System.CodeDom; using Microsoft.CSharp; using ...

  7. Poj1163 The Triangle(动态规划求最大权值的路径)

    一.Description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a pro ...

  8. 通过 命令提示符(cmd.exe)连接 Oracle 数据库

    通过IP 连接数据库: sqlplus userName/userPassword@//IP:port/SID 例:sqlplus testuser/123456@//192.168.0.1:1521 ...

  9. ES6学习之Iterator和For...of循环

    一.Iterator(它是一种接口,为各种不同的数据结构提供统一的访问机制.Iterator 接口主要供for...of消费) 默认Iterator接口(默认的 Iterator 接口部署在数据结构的 ...

  10. windows linux 使用python执行系统命令并将结果保存到变量

    最近需要用到os.system 发现不能赋值到变量 后查有更新的模块,如下: os.system os.spawn* os.popen* popen2.* commands.* 重新使用content ...