题目链接

树剖练手题,想复习下树剖。

第一次提交\(T\)成QQC

看我

???

看了数据范围的确挺恶心的,我的复杂度是\(O(Mlog^2N)\)的,数据范围有三段

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.

很极限就对了。难道是我常数太大了?那也不至于只对\(3\)个点吧。

我看了一下,原来我求\(size\)的时候没有加上子树的\(size\)...这样就会剖出假的重链。

我加上去,再交,还是\(T\)成QQC。

看我

......

原来是标记\(top\)的时候错了。改过来就\(A\)了。

虽然有两个细节错误,但是没有别的错误,也就是说我树剖大致模板和线段树都是一次写对的。。

话不多说。

树剖后用线段树来维护,维护最小值,黑点的值为\(dfs\)序,白点的值为\(INF\),每次查询找到链上的最小值即为答案。

因为从\(1\)到\(x\)是一条直链,越上的点也就是越靠近\(1\)的点,\(dfs\)序一定最小。

#include <cstdio>
#define INF 2147483647
#define re register
int s; char ch;
inline int read(){
s = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
inline int min(int a, int b){
return a > b ? b : a;
}
const int MAXN = 100010;
struct Edge{
int next, to;
}e[MAXN << 1];
int head[MAXN], num, n, m, a, b, w[MAXN];
inline void Add(int from, int to){
e[++num].to = to; e[num].next = head[from]; head[from] = num;
e[++num].to = from; e[num].next = head[to]; head[to] = num;
}
int dep[MAXN], size[MAXN], maxson[MAXN], top[MAXN], ID, dfn[MAXN], pos[MAXN], f[MAXN];
namespace SegTree{
#define left (now << 1)
#define right (now << 1 | 1)
int Min[MAXN << 2];
inline void pushup(int now){
Min[now] = min(Min[left], Min[right]);
}
void build(int now, int l, int r){
if(l == r){ Min[now] = INF; return; }
int mid = (l + r) >> 1;
build(left, l, mid);
build(right, mid + 1, r);
pushup(now);
}
void update(int now, int l, int r, int x){
if(l == r){ Min[now] = (w[pos[x]] ? x : INF); return; }
int mid = (l + r) >> 1;
if(x <= mid) update(left, l, mid, x);
else update(right, mid + 1, r, x);
pushup(now);
}
int query(int now, int l, int r, int wl, int wr){
if(l > wr || r < wl) return INF;
if(l >= wl && r <= wr) return Min[now];
int ans = INF, mid = (l + r) >> 1;
ans = min(ans, query(left, l, mid, wl, wr));
ans = min(ans, query(right, mid + 1, r, wl, wr));
return ans;
}
}using namespace SegTree;
void dfs1(int u, int fa){
size[u] = 1; f[u] = fa;
for(re int i = head[u]; i; i = e[i].next)
if(e[i].to != fa){
dfs1(e[i].to, u);
size[u] += size[e[i].to];
if(size[e[i].to] > size[maxson[u]])
maxson[u] = e[i].to;
}
}
void dfs2(int u, int rt){
dfn[u] = ++ID; pos[ID] = u; top[u] = rt;
if(maxson[u]) dfs2(maxson[u], rt);
for(re int i = head[u]; i; i = e[i].next)
if(e[i].to != f[u] && e[i].to != maxson[u])
dfs2(e[i].to, e[i].to);
}
inline int solve(int u){
int ans = INF;
while(top[u] != 1){
ans = min(ans, query(1, 1, n, dfn[top[u]], dfn[u]));
u = f[top[u]];
}
ans = min(ans, query(1, 1, n, dfn[1], dfn[u]));
return ans == INF ? -1 : pos[ans];
}
int main(){
n = read(); m = read();
for(re int i = 1; i < n; ++i)
Add(read(), read());
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
for(re int i = 1; i <= m; ++i){
a = read(); b = read();
if(!a){
w[b] ^= 1;
update(1, 1, n, dfn[b]);
}
else printf("%d\n", solve(b));
}
return 0;
}

最新文章

  1. 关于UIScrollerView的基本用法和代理
  2. 【Win10 应用开发】人脸识别
  3. poj 1655
  4. selenium python (八)定位frame中的对象
  5. js 写成类的形式 js 静态变量 js方法 属性 json类
  6. 连接Excel时出现未指定的错误
  7. java: Java中this和super的用法总结
  8. java数据结构和算法01(数组的简单使用)
  9. .NET尝试访问某方法失败
  10. 关于ajax的controller层返回jsp页面多个list
  11. 深度学习课程笔记(十二) Matrix Capsule
  12. for练习.html
  13. hdu 4915 括号匹配+巧模拟
  14. jpa 一对一
  15. 二,PHP会话机制---session的基本使用
  16. XMLHttpRequest cannot load ...谷歌浏览器跨域问题
  17. 升级mac xcode打包证书报错 git 报错
  18. Ant Design of Angular
  19. Google Tango初学者教程
  20. Codeforces 776C - Molly&#39;s Chemicals(思维+前缀和)

热门文章

  1. LintCode-105.复制带随机指针的链表
  2. TCP系列26—重传—16、重组包
  3. css3边框阴影效果
  4. cURL和file_get_contents实现模拟post请求
  5. 大全Kafka Streams
  6. 【Docker 命令】- build命令
  7. Python 时间推进器-->在当前时间的基础上推前n天 | CST时间转化标准日期格式
  8. hadoop SequenceFile示例
  9. POJ3348:Cows——题解
  10. 从MYSQL数据库查出指定格式的日期