SPOJ QTREE4 Query on a tree IV ——动态点分治
【题目分析】
同bzoj1095
然后WA掉了。
发现有负权边,只好把rmq的方式改掉。
然后T了。
需要进行底(ka)层(chang)优(shu)化。
然后还是T
下午又交就A了。
【代码】
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxe 200005
#define maxn 100005
#define inf (0x3f3f3f3f)
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
int h[maxe],to[maxe],ne[maxe],en=0,ban[maxn],n,m,rt,now,dst[maxn],Tree_rt,col[maxn],ans=-1,x,aim;
int b[maxn<<2],cnt=0,tag=0,pos[maxn],c[maxn<<2][20],_log[maxn<<2],w[maxe],d[maxn<<2][20],dep[maxn]; void add(int a,int b,int c) {to[en]=b;ne[en]=h[a];w[en]=c;h[a]=en++;}
struct Heap{
priority_queue <int> heap,del;
void Ins(int x){heap.push(x);}
void Del(int x){del.push(x);}
void Pop(){while (del.size()&&del.top()==heap.top()) del.pop(),heap.pop(); heap.pop();}
int Top(){while (del.size()&&del.top()==heap.top()) del.pop(),heap.pop(); return heap.top();}
int S_Top(){int tmp=Top(),ret;Pop();ret=Top();Ins(tmp);return ret; }
int Size(){return heap.size()-del.size();}
}s1[maxn],s2[maxn],lst; int mx[maxn],siz[maxn],size,fa[maxn];
char opt[11]; void dfs(int o,int fa)
{
if (!tag)b[++cnt]=o,pos[o]=cnt;
siz[o]=1;mx[o]=0;
for (int i=h[o];i>=0;i=ne[i])
if (!ban[to[i]]&&to[i]!=fa)
{
if (!tag) dep[to[i]]=dep[o]+1;
dfs(to[i],o);
if (!tag) b[++cnt]=o;
siz[o]+=siz[to[i]];
if (siz[to[i]]>mx[o]) mx[o]=siz[to[i]];
}
} void dfs_rt(int o,int fa)
{
if (max(mx[o],size-siz[o])<now) rt=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_rt(to[i],o);
} int lca(int a,int b)
{
int pa=pos[a],pb=pos[b];
if (pa>pb) swap(pa,pb);
int l=_log[pb-pa+1];
if (dep[d[pa][l]]<dep[d[pb-(1<<l)+1][l]]) return dst[d[pa][l]];
else return dst[d[pb-(1<<l)+1][l]];
} int dist(int a,int b)
{
if (a==0) a=Tree_rt;
if (b==0) b=Tree_rt;
return dst[a]+dst[b]-2*lca(a,b);
} void dfs_add(int o,int fa)
{
s1[rt].Ins((dist(o,aim)));
for (int i=h[o];i>=0;i=ne[i])
if (!ban[to[i]]&&to[i]!=fa)
dfs_add(to[i],o);
} void Divide(int o,int fat)
{
int root;
dfs(o,-1); size=siz[o]; now=inf;
dfs_rt(o,-1); root=rt;
if (fat) fa[root]=fat;
ban[root]=1;
aim=fat;
dfs_add(root,-1);
s2[fat].Ins(s1[root].Top());
if (!col[root]) s2[root].Ins(0);
for (int i=h[root];i>=0;i=ne[i])
if (!ban[to[i]]) Divide(to[i],root);
if (s2[root].Size()>=2)
{
int tmp=s2[root].Top()+s2[root].S_Top();
lst.Ins(tmp);
}
} void dfs_dist(int o,int fat)
{
for (int i=h[o];i>=0;i=ne[i])
if (to[i]!=fat) dst[to[i]]=dst[o]+w[i],dfs_dist(to[i],o);
} void Delete(int o)
{
if (s2[o].Size()>=2) lst.Del(s2[o].Top()+s2[o].S_Top());
s2[o].Del(0);
if (s2[o].Size()>=2)
{
int tmp=s2[o].Top()+s2[o].S_Top(); lst.Ins(tmp);
}
if (s2[o].Size()>0) ans=max(ans,0);
int now=o;
while (now)
{
int fat=fa[now];
if (s2[fat].Size()>=2)lst.Del(s2[fat].Top()+s2[fat].S_Top());
int tmp=s1[now].Top();
s1[now].Del(dist(o,fat));
if (s1[now].Size()==0||tmp!=s1[now].Top())
{
s2[fat].Del(tmp);
if (s1[now].Size()>0) s2[fat].Ins(s1[now].Top());
}
if (s2[fat].Size()>=2)
{
int tmp=s2[fat].Top()+s2[fat].S_Top();
lst.Ins(tmp);
}
if (s2[fat].Size()>0) ans=max(ans,0);
now=fat;
}
} void Insert(int o)
{
if (s2[o].Size()>=2)
{
lst.Del(s2[o].Top()+s2[o].S_Top());
}
s2[o].Ins(0);
if (s2[o].Size()>=2)
{
int tmp=s2[o].Top()+s2[o].S_Top();lst.Ins(tmp);
}
if (s2[o].Size()>0) ans=max(ans,0);
int now=o;
while (now)
{
int fat=fa[now];
if (s2[fat].Size()>=2) lst.Del(s2[fat].Top()+s2[fat].S_Top());
int tmp,flag=0;
if (s1[now].Size()==0) flag=1;
else tmp=s1[now].Top();
s1[now].Ins(dist(o,fat));
if (flag||tmp!=s1[now].Top())
{
if (!flag) s2[fat].Del(tmp);
s2[fat].Ins(s1[now].Top());
}
if (s2[fat].Size()>=2)
{
int tmp=s2[fat].Top()+s2[fat].S_Top();
lst.Ins(tmp);
}
if (s2[fat].Size()>0) ans=max(ans,0);
now=fat;
}
} int Getint()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} int main()
{
memset(h,-1,sizeof h);
n=Getint();
F(i,1,n-1)
{
int a,b,c;
a=Getint();b=Getint();c=Getint();
add(a,b,c);add(b,a,c);
}
tag=1;
dfs(1,-1);
now=inf; size=siz[1]; dfs_rt(1,-1); dfs_dist(rt,-1);
tag=0;
dfs(rt,-1);
tag=1;
F(i,2,cnt) _log[i]=_log[i>>1]+1;
F(i,1,cnt) d[i][0]=b[i];
F(j,1,_log[cnt])
for (int i=1;i+(1<<j)-1<=cnt;++i)
{
if (dep[d[i][j-1]]<dep[d[i+(1<<j-1)][j-1]]) d[i][j]=d[i][j-1];
else d[i][j]=d[i+(1<<j-1)][j-1];
}
Tree_rt=rt;
Divide(1,0);
scanf("%d",&m);
F(i,1,m)
{
scanf("%s",opt);
switch(opt[0])
{
case 'A': if (lst.Size()) ans=max(ans,lst.Top());printf("%d\n",ans); break;
case 'C': x=Getint();ans=-1; if (!col[x]) Delete(x); else Insert(x); col[x]^=1; break;
}
}
}
SPOJ QTREE4 Query on a tree IV ——动态点分治的更多相关文章
- SPOJ QTREE4 - Query on a tree IV
You are given a tree (an acyclic undirected connected graph) with N nodes, and nodes numbered 1,2,3. ...
- SPOJ QTREE4 - Query on a tree IV 树分治
题意: 给出一棵边带权的树,初始树上所有节点都是白色. 有两种操作: C x,改变节点x的颜色,即白变黑,黑变白 A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为0). 分析: ...
- SPOJ - QTREE4 Query on a tree IV 边分治
题目传送门 题意:有一棵数,每个节点有颜色,黑色或者白色,树边有边权,现在有2个操作,1修改某个点的颜色, 2询问2个白点的之前的路径权值最大和是多少. 题解: 边分治思路. 1.重构图. 因为边分治 ...
- SPOJ QTREE Query on a tree V ——动态点分治
[题目分析] QTREE4的弱化版本 建立出分治树,每个节点的堆表示到改点的最近白点距离. 然后分治树上一直向上,取min即可. 正确性显然,不用担心出现在同一子树的情况(不会是最优解),请自行脑补. ...
- SPOJ 375. Query on a tree (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- 2019.02.16 spoj Query on a tree IV(链分治)
传送门 题意简述: 捉迷藏强化版(带有边权,可以为负数) 思路:好吧这次我们不用点分树,我们用听起来更屌的链分治. 直接把树剖成若干条重链,这样保证从任意一个点跳到根节点是不会跳超过logloglog ...
- SP2666 QTREE4 - Query on a tree IV(LCT)
题意翻译 你被给定一棵n个点的带边权的树(边权可以为负),点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的权值之和. 一开始所有的点都是白色的. 要求作以下 ...
- SPOJ QTREE4 SPOJ Query on a tree IV
You are given a tree (an acyclic undirected connected graph) with N nodes, and nodes numbered 1,2,3. ...
随机推荐
- git的基本使用命令操作
Linux操作命令行: mkdir - 创建文件夹, cd - 切换文件路径 pwd - 显示文件路径 ls -ah - 可以查看隐藏的文件夹名(.git) cat 文件 ...
- Android 图片在SD卡及包下的存储
public class FileBitmap { /** * 获取sd卡中的bitmap,bitmap可见 * * @param bitmap * 读取bitmap的路径 * @return bit ...
- MySQL备份还原介绍
window系统下 1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u dbuser -p dbname > dbname.sql ...
- 如何在Kubernetes里创建一个Nginx service
Jerry之前的文章如何在Kubernetes里创建一个Nginx应用,已经使用kubectl命令行创建了Pod,但是在kubernetes中,Pod的IP地址会随着Pod的重启而变化,因此用Pod的 ...
- java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal问题解决
使用Maven构建项目并加载spring配置文件时,报如下异常 Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTrav ...
- HTML5微信播放全屏问题的解决方法
在ios和安卓手机里的微信下播放视频时,会遇到不少问题,例如需要手动点击,视频才会播放,并且视频会跳出微信框,出现控制条,如果视频不是腾讯视频,播放完毕会出现腾讯视频的广告推送等问题 解决办法:给vi ...
- MFC:AfxLoadLibrary-将指定的 DLL 映射到调用进程的地址空间
Visual Studio 2012 - Visual C++ LoadLibrary 和 AfxLoadLibrary 进程调用 LoadLibrary (或 AfxLoadLibrary) 以显式 ...
- Bootstrap历练实例:导航中的表单
Bootstrap历练实例:导航中的表单,它是使用class.navbar-form类,这确保了表单适当的垂直对齐和在较窄的视口中折叠的行为,使用这个对齐方式选项来决定导航栏中的内容放置在哪里. 实例 ...
- 稳定性 耗时 gc 过长问题排查 和工具
自己的另外一篇: http://www.cnblogs.com/fei33423/p/7805186.html 偶有耗时抖动? gc 也有长耗时? fullgc 也是? 有同学反馈 swap 可能导致 ...
- shell脚本,判断给出的字符串是否相等。
第一种方法[root@localhost wyb]# .sh #!/bin/bash #判断给出的字符串是否相等 read -p "Please Input a number:" ...