[COJ0968]WZJ的数据结构(负三十二)

试题描述

给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着。请你设计一个数据结构,回答M次操作。

1 x:将节点x上的灯拉一次,即亮变灭,灭变亮。

2 x k:询问当前所有亮灯的节点中距离x第k小的距离(注意如果x亮着也算入)。

输入

第一行为一个正整数N。
第二行到第N行每行三个正整数ui,vi,wi。表示一条树边从ui到vi,距离为wi。
第N+1行为一个正整数M。
最后M行每行三个或两个正整数,格式见题面。

输出

对于每个询问操作,输出答案。

输入示例


输出示例


数据规模及约定

1<=N,M<=50000
1<=x,ui,vi<=N,1<=v,wi<=1000

题解

动态点分治。对于每个节点我们开一个平衡树,每次修改节点 u 时把 u 以及它到根节点的路径上所有节点上的平衡树都更新一下;对于询问我们先二分答案 x,然后查找一下 u 到根节点路径上所有平衡树,看小于等于 x 的值是否小于 k 个。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 50010
#define maxm 100010
#define maxlog 17 int n, m, head[maxn], nxt[maxm], to[maxm], dist[maxm]; void AddEdge(int a, int b, int c) {
to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
return ;
} int dep[maxn], mnd[maxlog][maxn<<1], Log[maxn<<1], clo, pos[maxn];
void build(int u, int pa) {
mnd[0][pos[u] = ++clo] = dep[u];
for(int e = head[u]; e; e = nxt[e]) if(to[e] != pa)
dep[to[e]] = dep[u] + dist[e], build(to[e], u), mnd[0][++clo] = dep[u];
return ;
}
void rmq_init() {
Log[1] = 0;
for(int i = 2; i <= clo; i++) Log[i] = Log[i>>1] + 1;
for(int j = 1; (1 << j) <= clo; j++)
for(int i = 1; i + (1 << j) - 1 <= clo; i++)
mnd[j][i] = min(mnd[j-1][i], mnd[j-1][i+(1<<j-1)]);
return ;
}
int cdist(int a, int b) {
int ans = dep[a] + dep[b];
int l = pos[a], r = pos[b]; if(l > r) swap(l, r);
int t = Log[r-l+1];
return ans - (min(mnd[t][l], mnd[t][r-(1<<t)+1]) << 1);
} int rt, size, siz[maxn], f[maxn];
bool vis[maxn];
void getrt(int u, int pa) {
siz[u] = 1; f[u] = 0;
for(int e = head[u]; e; e = nxt[e]) if(to[e] != pa && !vis[to[e]]) {
getrt(to[e], u);
siz[u] += siz[to[e]];
f[u] = max(f[u], siz[to[e]]);
}
f[u] = max(f[u], size - siz[u]);
if(f[rt] > f[u]) rt = u;
return ;
}
int fa[maxn];
void solve(int u) {
vis[u] = 1;
for(int e = head[u]; e; e = nxt[e]) if(!vis[to[e]]) {
f[rt = 0] = size = siz[u]; getrt(to[e], u);
fa[rt] = u; solve(rt);
}
return ;
} #define maxnode 1600010 struct Node {
int v, r, siz;
Node() {}
Node(int _, int __): v(_), r(__) {}
} ns[maxnode];
int ToT, ch[maxnode][2], Fa[maxnode], rec[maxnode], rcnt;
inline int getnode() {
if(rcnt) {
int o = rec[rcnt--];
ch[o][0] = ch[o][1] = Fa[o] = 0;
return o;
}
return ++ToT;
}
inline void maintain(int o) {
if(!o) return ;
ns[o].siz = ns[ch[o][0]].siz + 1 + ns[ch[o][1]].siz;
return ;
}
inline void rotate(int u) {
int y = Fa[u], z = Fa[y], l = 0, r = 1;
if(z) ch[z][ch[z][1]==y] = u;
if(ch[y][1] == u) swap(l, r);
Fa[u] = z; Fa[y] = u; Fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
inline void Insert(int& o, int v) {
if(!o) {
ns[o = getnode()] = Node(v, rand());
return maintain(o);
}
bool d = v > ns[o].v;
Insert(ch[o][d], v); Fa[ch[o][d]] = o;
if(ns[ch[o][d]].r > ns[o].r) {
int t = ch[o][d];
rotate(t); o = t;
}
return maintain(o);
}
inline void Del(int& o, int v) {
if(!o) return ;
if(ns[o].v == v) {
if(!ch[o][0] && !ch[o][1]) rec[++rcnt] = o, o = 0;
else if(!ch[o][0]) {
int t = ch[o][1]; Fa[t] = Fa[o]; rec[++rcnt] = o; o = t;
}
else if(!ch[o][1]) {
int t = ch[o][0]; Fa[t] = Fa[o]; rec[++rcnt] = o; o = t;
}
else {
bool d = ns[ch[o][1]].r > ns[ch[o][0]].r;
int t = ch[o][d]; rotate(t); o = t;
Del(ch[o][d^1], v);
}
}
else {
bool d = v > ns[o].v;
Del(ch[o][d], v);
}
return maintain(o);
}
inline int query(int o, int x) {
if(!o) return 0;
int ls = ch[o][0] ? ns[ch[o][0]].siz : 0;
if(x < ns[o].v) return query(ch[o][0], x);
return ls + 1 + query(ch[o][1], x);
} int Rt[maxn], Rtfa[maxn];
bool lit[maxn];
void update(int s) {
if(lit[s]) Insert(Rt[s], 0);
else Del(Rt[s], 0);
for(int u = s; fa[u]; u = fa[u]) {
int d = cdist(fa[u], s);
if(lit[s]) Insert(Rt[fa[u]], d), Insert(Rtfa[u], d);
else Del(Rt[fa[u]], d), Del(Rtfa[u], d);
}
lit[s] ^= 1;
return ;
}
int ask(int s, int x) {
int ans = query(Rt[s], x);
for(int u = s; fa[u]; u = fa[u]) {
int d = cdist(fa[u], s);
ans += query(Rt[fa[u]], x - d) - query(Rtfa[u], x - d);
}
return ans;
} int main() {
n = read();
int sum = 0;
for(int i = 1; i < n; i++) {
int a = read(), b = read(), c = read(); sum += c;
AddEdge(a, b, c);
} build(1, 0); rmq_init();
f[rt = 0] = size = n; getrt(1, 0);
solve(rt); memset(lit, 1, sizeof(lit));
for(int i = 1; i <= n; i++) update(i);
int q = read();
while(q--) {
int tp = read(), u = read();
if(tp == 1) update(u);
if(tp == 2) {
int k = read();
int l = 0, r = sum;
while(l < r) {
int mid = l + r >> 1;
if(ask(u, mid) < k) l = mid + 1; else r = mid;
}
printf("%d\n", l);
}
} return 0;
}

[COJ0968]WZJ的数据结构(负三十二)的更多相关文章

  1. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  2. 数据结构(三十二)图的遍历(DFS、BFS)

    图的遍历和树的遍历类似.图的遍历是指从图中的某个顶点出发,对图中的所有顶点访问且仅访问一次的过程.通常有两种遍历次序方案:深度优先遍历和广度优先遍历. 一.深度优先遍历 深度优先遍历(Depth_Fi ...

  3. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  4. COJ970 WZJ的数据结构(负三十)

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  5. COJ 0970 WZJ的数据结构(负三十)树分治

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  6. [COJ0970]WZJ的数据结构(负三十)

    [COJ0970]WZJ的数据结构(负三十) 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为 ...

  7. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

  8. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. COJ 1003 WZJ的数据结构(三)ST表

    WZJ的数据结构(三) 难度级别:B: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的 ...

随机推荐

  1. 数学 Codeforces Round #308 (Div. 2) B. Vanya and Books

    题目传送门 /* 水题:求总数字个数,开long long竟然莫名其妙WA了几次,也没改啥又对了:) */ #include <cstdio> #include <iostream& ...

  2. Spring @Resource、@Autowired、@Qualifier区别

    @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...

  3. 用C#操作word替换字符,用spire

    这两天想写个小程序,是用C#操作word文档的.许多人都对微软本身的解决方案COM组件十分不看好,比如需要本机安装office等等,总之吐槽很多,直接放弃. 搜到一个国产的npoi库,据说操作简单功能 ...

  4. ReactJS-0-React介绍

    React介绍: React是一个库而不是一个MVC框架,因为React只负责解决MVC框架中V(View)层面的问题,React致力于创建可重用的UI组件.(React is a library f ...

  5. jQuery实现复选框的全选与全不选

    对于复选框的选中checked属性,实在是无力吐槽. 从上图可以看出,当复选框不设置checked属性时,默认没有被选中:其它三种情况,设置checked属性但不设置属性值即置空,或者将checked ...

  6. Android拍照得到全尺寸图片并进行压缩/拍照或者图库选择 压缩后 图片 上传

    http://www.jb51.net/article/77223.htm https://www.cnblogs.com/breeze1988/p/4019510.html

  7. tomcat 启动失败 和闪退 和 启动成功却没有页面显示

    1.解压版tomcat 将tomcat解压至英文目录下, 在系统环境变量里面配置 JAVA_HOME 和CATALINA_HOME (就是tomcat的安装目录) 在path中配置 %CATALINA ...

  8. applicationContext.getBean(“loginEntity”)

    <!-- 指定Spring需要扫描的包,并将所有是别的类放到容器中,便于识别被注解的受托管bean --> <context:component-scan base-package= ...

  9. Linux下Eclipse连接小米手机真机调试

    以前用Ubuntu 12.04可以真机调试,连上手机就可以了,上次看pear os 好看于是下了个玩玩(界面风格像mac 买不起,仿得起),这次想开发安卓发现真机调试不了了...于是乎各种找资料,各种 ...

  10. IDEA安装使用

    下载地址: https://www.jetbrains.com/idea/download/previous.html 这里我下载的是:2016.3.8版本的 安装: 安装成功后,需要秘钥的话,在 h ...