WZJ的数据结构(负三十二)
难度级别:D; 运行时间限制:5000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

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

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

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

输入
第一行为一个正整数N。
第二行到第N行每行三个正整数ui,vi,wi。表示一条树边从ui到vi,距离为wi。
第N+1行为一个正整数M。
最后M行每行三个或两个正整数,格式见题面。
输出
对于每个询问操作,输出答案。
输入示例
10
1 2 2
1 3 1
1 4 3
1 5 2
4 6 2
4 7 1
6 8 1
7 9 2
7 10 1
5
2 1 4
1 5
2 1 4
2 1 9
2 1 1
输出示例
2
3
6
0
其他说明
1<=N,M<=50000
1<=x,ui,vi<=N,1<=v,wi<=1000

动态树分治的码农题啦。

对于每个节点用两棵Treap分别维护子树中亮灯的节点到其距离与子树中亮灯的节点到其父亲距离。

修改直接insert/remove。

询问先二分答案,转化成判定问题,这很容易在Treap上做。

修改O(log^2n),询问O(log^3n),常数还挺小的。

说起来还真是简单呢!写了2h+。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
struct Node {
Node* ch[];
int r,s,v;
void maintain() {s=ch[]->s+ch[]->s+;}
}nodes[maxn*],*null=&nodes[];
int ToT;queue<Node*> Q;
Node* newnode(int v) {
Node* o;
if(Q.empty()) o=&nodes[++ToT];
else o=Q.front(),Q.pop();
o->v=v;o->s=;o->ch[]=o->ch[]=null;o->r=rand();
return o;
}
void del(Node* &o) {Q.push(o);o=null;}
void rotate(Node* &o,int d) {
Node* k=o->ch[d^];o->ch[d^]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void insert(Node* &o,int v) {
if(o==null) o=newnode(v);
else {
int d=v>o->v;insert(o->ch[d],v);
if(o->ch[d]->r>o->r) rotate(o,d^);
else o->maintain();
}
}
void remove(Node* &o,int v) {
if(o->v==v) {
Node* k=o;
if(o->ch[]==null) o=o->ch[],del(k);
else if(o->ch[]==null) o=o->ch[],del(k);
else {
int d=o->ch[]->r>o->ch[]->r;
rotate(o,d);remove(o->ch[d],v);
}
}
else remove(o->ch[v>o->v],v);
if(o!=null) o->maintain();
}
int query(Node* &o,int v) {
if(o==null) return ;
if(v>o->v) return query(o->ch[],v)+o->ch[]->s+;
return query(o->ch[],v);
}
int n,m,first[maxn],next[maxn<<],to[maxn<<],dis[maxn<<],e;
void AddEdge(int w,int v,int u) {
dis[++e]=w;to[e]=v;next[e]=first[u];first[u]=e;
dis[++e]=w;to[e]=u;next[e]=first[v];first[v]=e;
}
int dep[maxn],mn[maxn<<][],Log[maxn<<],cnt,pos[maxn];
void dfs(int x,int fa) {
mn[++cnt][]=dep[x];pos[x]=cnt;
ren if(to[i]!=fa) {
dep[to[i]]=dep[x]+dis[i];
dfs(to[i],x);
mn[++cnt][]=dep[x];
}
}
void pre() {
Log[]=-;
rep(i,,cnt) Log[i]=Log[i>>]+;
for(int j=;(<<j)<=cnt;j++)
for(int i=;i+(<<j)-<=cnt;i++)
mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
}
int dist(int x,int y) {
int ans=dep[x]+dep[y];
x=pos[x];y=pos[y];if(x>y) swap(x,y);
int k=Log[y-x+];
return ans-*min(mn[x][k],mn[y-(<<k)+][k]);
}
int f[maxn],s[maxn],vis[maxn],size,rt;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(to[i]!=fa&&!vis[to[i]]) {
getroot(to[i],x);
s[x]+=s[to[i]];
maxs=max(maxs,s[to[i]]);
}
f[x]=max(size-s[x],maxs);
if(f[x]<f[rt]) rt=x;
}
int fa[maxn];
void solve(int x,int F) {
vis[x]=;fa[x]=F;
ren if(!vis[to[i]]) {
f[]=size=s[to[i]];getroot(to[i],rt=);
solve(rt,x);
}
}
Node *root[maxn],*root2[maxn];
void turn_on(int x) {
insert(root[x],);
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
insert(root[fa[i]],D);
insert(root2[i],D);
}
}
void turn_off(int x) {
remove(root[x],);
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
remove(root[fa[i]],D);
remove(root2[i],D);
}
}
int query(int x,int v) {
int ans=query(root[x],++v);
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
ans+=query(root[fa[i]],v-D)-query(root2[i],v-D);
}
return ans;
}
int mark[maxn];
int main() {
n=read();
rep(i,,n) root[i]=root2[i]=null;
rep(i,,n) AddEdge(read(),read(),read());
dfs(,);pre();
f[]=size=n;getroot(,rt=);
solve(rt,);
rep(i,,n) turn_on(i);
m=read();
while(m--) {
if(read()==) {
int x=read();
if(mark[x]) turn_on(x);
else turn_off(x);
mark[x]^=;
}
else {
int x=read(),k=read();
int l=,r=<<,mid;
while(l<r) if(query(x,mid=l+r>>)>=k) r=mid; else l=mid+;
printf("%d\n",l);
}
}
return ;
}

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

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

    [COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...

  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. Android自动登录与记住密码

    // 获取实例对象 sp = this.getSharedPreferences("userInfo", Context.MODE_WORLD_READABLE); rem_pw ...

  2. php远程抓取网站图片并保存

    以前看到网上别人说写程序抓取网页图片的,感觉挺神奇,心想什么时候我自己也写一个抓取图片的方法! 刚好这两天没什么事,就参考了网上一个php抓取图片代码,重点借鉴了 匹配img标签和其src属性正则的写 ...

  3. 基础知识《二》java的基本类型

    一.java基本数据类型 Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte.short.int.long.float.double.数值类型 ...

  4. java调用matlab函数

    如何将实验结果在matlab中可视化呢,下面使用java语言编程,调用matlab中的函数: 本人安装的是Matlab7.11.0 (R2010a)和 Eclipse 4.2 : 1)首先设置环境变量 ...

  5. jqGrid 各种参数 详解

    JQGrid JQGrid是一个在jquery基础上做的一个表格控件,以ajax的方式和服务器端通信. JQGrid Demo 是一个在线的演示项目.在这里,可以知道jqgrid可以做什么事情. 下面 ...

  6. iOS 和 Android 触摸事件传递

    先看文章,写得很好 ios 触摸事件传递 http://www.cnblogs.com/Quains/p/3369132.html 另外一篇 http://blog.csdn.net/yongyinm ...

  7. Java for LeetCode 062 Unique Paths

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  8. Java for LeetCode 035 Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  9. DP:Ant Counting(POJ 3046)

    数蚂蚁 题目大意:一只牛想数蚂蚁,蚂蚁分成很多组,每个组里面有很多只蚂蚁,现在问你有多少种组合方式 (说白了就是问1,1,1,...,2...,3...,4...)这些东西有多少种排列组合方式 这一道 ...

  10. error: Refusing to undefine while domain managed save image exists

    [root@ok libvirt]# virsh undefine win7 error: Refusing to undefine while domain managed save image e ...