SPOJ QTREE Query on a tree V ——动态点分治
【题目分析】
QTREE4的弱化版本
建立出分治树,每个节点的堆表示到改点的最近白点距离。
然后分治树上一直向上,取min即可。
正确性显然,不用担心出现在同一子树的情况(不会是最优解),请自行脑补。
然后弱渣我写了1.5h
【代码】
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define inf 0x3f3f3f3f
#define maxe 200005
#define maxn 100005
struct Heap{
priority_queue<int, vector<int>, greater<int> > heap,del;
void Ins(int x){heap.push(x);}
void Del(int x){del.push(x);}
int Size(){return heap.size()-del.size();}
int Top(){while (del.size()&&heap.top()==del.top()) heap.pop(),del.pop();return heap.top();}
}s[maxn]; int h[maxe],to[maxe],ne[maxe],en=0,n,m,_log[maxn<<2],a[maxn<<2][20],col[maxn],tag=0,x;
int siz[maxn],mx[maxn],root,now,b[maxn<<2],top=0,pos[maxn],size,ban[maxn],T_rt,dst[maxn],fa[maxn]; void add(int a,int b){to[en]=b;ne[en]=h[a];h[a]=en++;} void dfs(int o,int fa)
{
siz[o]=1; mx[o]=0;
if (!tag) b[++top]=o,pos[o]=top;
for (int i=h[o];i>=0;i=ne[i])
if (!ban[to[i]]&&to[i]!=fa)
{
dfs(to[i],o);
if (!tag) b[++top]=o;
siz[o]+=siz[to[i]];
mx[o]=max(mx[o],siz[to[i]]);
}
} void dfs_root(int o,int fa)
{
if (now>max(mx[o],size-siz[o])) root=o,now=max(mx[o],size-siz[o]);
for (int i=h[o];i>=0;i=ne[i])
if (!ban[to[i]]&&to[i]!=fa)
dfs_root(to[i],o);
} void dfs_dist(int o,int fa)
{
for (int i=h[o];i>=0;i=ne[i])
if (!ban[to[i]]&&to[i]!=fa)
dst[to[i]]=dst[o]+1,dfs_dist(to[i],o);
} void Divide(int o,int fat)
{
dfs(o,-1);now=inf;size=siz[o];dfs_root(o,-1);
int rt=root; ban[rt]=1;fa[rt]=fat;
for (int i=h[rt];i>=0;i=ne[i])
if (!ban[to[i]]) Divide(to[i],rt);
} int dist(int x,int y)
{
int ret=dst[x]+dst[y];
x=pos[x],y=pos[y];
if (x>y) swap(x,y);
int l=_log[y-x+1];
return ret-2*min(a[x][l],a[y-(1<<l)+1][l]);
} void Delete(int o)
{
s[o].Del(0);
int now=fa[o];
while (now)
{
s[now].Del(dist(o,now));
now=fa[now];
}
} void Insert(int o)
{
s[o].Ins(0);
int now=fa[o];
while (now)
{
s[now].Ins(dist(o,now));
now=fa[now];
}
} int query(int o)
{
int ret=inf;
if (s[o].Size()) ret=min(ret,s[o].Top());
int now=fa[o];
while (now)
{
if (s[now].Size()) ret=min(s[now].Top()+dist(o,now),ret);
now=fa[now];
}
if (ret==inf) printf("-1\n");
else printf("%d\n",ret);
} int main()
{
memset(h,-1,sizeof h);
scanf("%d",&n);
F(i,1,n-1)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
tag=1; dfs(1,-1); size=siz[1]; now=inf; dfs_root(1,-1); T_rt=root;
tag=0; dfs(root,-1); dfs_dist(root,-1); tag=1;
F(i,2,top) _log[i]=_log[i>>1]+1;
F(i,1,top) a[i][0]=dst[b[i]];
F(j,1,_log[top])
for (int i=1;i+(1<<j)-1<=top;++i)
a[i][j]=min(a[i][j-1],a[i+(1<<j-1)][j-1]);
Divide(T_rt,0);
scanf("%d",&m);
F(i,1,m)
{
int opt; scanf("%d",&opt);
switch(opt)
{
case 0:scanf("%d",&x);if (col[x]) Delete(x); else Insert(x); col[x]^=1; break;
case 1:scanf("%d",&x);query(x); break;
}
}
}
SPOJ QTREE Query on a tree V ——动态点分治的更多相关文章
- SPOJ QTREE Query on a tree V
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...
- SPOJ QTREE4 Query on a tree IV ——动态点分治
[题目分析] 同bzoj1095 然后WA掉了. 发现有负权边,只好把rmq的方式改掉. 然后T了. 需要进行底(ka)层(chang)优(shu)化. 然后还是T 下午又交就A了. [代码] #in ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- SPOJ 375. Query on a tree (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- SPOJ QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
- SPOJ QTREE - Query on a tree 【树链剖分模板】
题目链接 引用到的大佬博客 代码来自:http://blog.csdn.net/jinglinxiao/article/details/72940746 具体算法讲解来自:http://blog.si ...
- SPOJ QTREE Query on a tree
题意:给一颗n个点的树,有两种操作CHANGE i ti : 把第i条边的权变为tiQUERY a b : 问点a 到 点b 之间的边的最大权 思路:树剖处理边权.由于是边,所以只需要把边权处理到子节 ...
随机推荐
- 再用python写一个文本处理的东东
朋友遇到一点麻烦,我自告奋勇帮忙.事情是这样的: - 他们的业务系统中,数据来自一个邮箱: - 每一个邮件包含一条记录: - 这些记录是纯文本的,字段之间由一些特殊字符分隔: - 他们需要从邮箱中批量 ...
- 利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...
- kettle数据同步方法
1.实时性要求不高,采用全删全插的方式(适合于维度表.大数据量表) 2.有时间维度,直接从事实表同步的数据,可以采用根据时间字段进行筛选,增量同步.这个网上有很多例子,就不重复写了. 3.没有时间维度 ...
- codevs 1992 聚会
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 小S 想要从某地出发去同学k的家中参加一个party,但要有去有回.他想让所用的 ...
- OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)
适用于: Oracle Database - Enterprise Edition - 版本 10.2.0.1 到 11.2.0.1.0 [发行版 10.2 到 11.2]本文档所含信息适用于所有平台 ...
- java并发编程:Executor、Executors、ExecutorService
1.Executor和ExecutorService Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable comma ...
- 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"
如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...
- Open Scene Graph:让VS支持不含后缀的头文件
让VS支持不含后缀的头文件 看OSG源码时,会遇到不含后缀的头文件无定位信息的尴尬,很让人苦恼. 就是单击VS中“工具菜单栏”——>”选项(O)….”如下图所示: 菜单项,弹出选项对话框,单击“ ...
- OS复习
提纲 一 操作系统的定义,各章节名词定义. 分时多道- OS四大特征,五大功能. 二 进程 创建终止挂起激活 PCB 原语:创建终止挂起激活唤醒 互斥和同步,临界资源,临界区 信号量的基础概念,受保护 ...
- C语言实现链表及其操作
#include <stdio.h> #include <stdlib.h> //定义节点 typedef struct Node { int data; struct Nod ...