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. OpenGL实现三维立方体交互

    http://yunpan.cn/cs62JgxTNs98C  (提取码:668e)

  2. linux 下如何查看和踢除正在登陆的其它用户 ==>Linux下用于查看系统当前登录用户信息的4种方法

    在linux系统中用pkill命令踢出在线登录用户 由于linux服务器允许多用户登录,公司很多人知道密码,工作造成一定的障碍 所以需要有时踢出指定的用户 1/#who   查出当前有那些终端登录(用 ...

  3. tcp/IP点对点通信程序

    点对点的通信 服务器端与客户端在建立连接之后创建一个进程 服务器端: 子进程用于接收主机的输入并将数据发送出去.父进程用于接收客户端的数据并输出到主机. 子进程一直等待主机的输入,输入的数据放在发送缓 ...

  4. 无论IT代码系统还是人生都是有惯性的

    是的,这和IT系统和代码没有什么关系:鸡汤式的文章,看烦了的就关掉吧,想看的请听我碎碎念.惯性本是物理学研究的问题,这里没有要研究物理学里的惯性.惯性无时无刻地发生在我们的日常生活中,只是你我都没有察 ...

  5. Transfer-Encoding: chunked

    Http1.1中 使用 chunked 编码传送时 没有CONTENT_LENGTH,下载之前无法确定要下载的大小. Wininet中已经内嵌该传输协议,要查看chunked块的大小只能socket底 ...

  6. codeforces B. Jeff and Periods 解题报告

    题目链接:http://codeforces.com/problemset/problem/352/B 题目意思:给出一个长度为n的序列   a1, a2, ..., an(序号i,1 <= i ...

  7. HDU 3835 R(N)

    R(N) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. [转]Java 内部类笔记

    内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的.内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权 ...

  9. Android常用查询网站

    一.老罗的Android之旅爱生活,爱Android http://blog.csdn.net/luoshengyang 二.Android中文API http://www.android-doc.c ...

  10. jquery easy ui 1.3.4 数据表格(DataGrid)(8)

    8.1.创建DataGrid html代码 <table id="dg"></table> $("#dg").datagrid({ // ...