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...,N. Each edge has an integer value assigned to it(note that the value can be negative). Each node has a color, white or black. We define dist(a, b) as the sum of the value of the edges on the path from node a to node b.
All the nodes are white initially.
We will ask you to perfrom some instructions of the following form:
- C a : change the color of node a.(from black to white or from white to black)
- A : ask for the maximum dist(a, b), both of node a and node b must be white(a can be equal to b). Obviously, as long as there is a white node, the result will alway be non negative.
Input
- In the first line there is an integer N (N <= 100000)
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of value c (-1000 <= c <= 1000)
- In the next line, there is an integer Q denotes the number of instructions (Q <= 100000)
- In the next Q lines, each line contains an instruction "C a" or "A"
Output
For each "A" operation, write one integer representing its result. If there is no white node in the tree, you should write "They have disappeared.".
Example
Input:
3
1 2 1
1 3 1
7
A
C 1
A
C 2
A
C 3
A Output:
2
2
0
They have disappeared.
给出一棵边带权的树,初始树上所有节点都是白色。
有两种操作:
C x,改变节点x的颜色,即白变黑,黑变白
A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为0)。
树 边分治
试着写了边分治,花式WAWAWA,最后不得已还是开启了标准代码比对。
这么复杂的东西估计过几天就忘,悲伤
果然加上虚点以后内存占用超大啊……边要开到mxn<<4
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int INF=1e8;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*-''+ch;ch=getchar();}
return x*f;
}
struct edge{
int v,nxt;int w;
}e[mxn<<],eg[mxn<<];
int hd[mxn],mct=;
int tmp[mxn];
void add_edge(int u,int v,int w){//虚点图
e[++mct].v=v;e[mct].nxt=hd[u];e[mct].w=w;hd[u]=mct;return;
}
void add1(int u,int v,int w){//原图
eg[++mct].v=v;eg[mct].nxt=tmp[u];eg[mct].w=w;tmp[u]=mct;return;
}
int n,m;
int c[mxn];//颜色 void Rebuild(int u,int fa){//建立添加了虚点的新图
int ff=;
for(int i=tmp[u];i;i=eg[i].nxt){//tmp存原图边
int v=eg[i].v;
if(v==fa)continue;
if(!ff){
add_edge(u,v,eg[i].w);
add_edge(v,u,eg[i].w);
ff=u;
Rebuild(v,u);
}
else{
c[++n]=;//添加虚点
add_edge(ff,n,);add_edge(n,ff,);
add_edge(n,v,eg[i].w);
add_edge(v,n,eg[i].w);
ff=n;
Rebuild(v,u);
}
}
return;
}
struct node{
int rt,len,ans;
int lc,rc;
priority_queue<pair<int,int> >q;
}t[mxn<<];
bool del[mxn<<];
int pos,mini,mid;
int sz[mxn],tot=;
void DFS_S(int u,int d,int fa){//计算子树各结点距离
add1(u,pos,d);//用原图的空间来存边分治的点边关系
//从当前结点向"管辖它的边代表的结点"连边
if(!c[u]) t[pos].q.push(make_pair(d,u));
sz[u]=;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa || del[i])continue;
DFS_S(v,d+e[i].w,u);
sz[u]+=sz[v];
}
return;
}
void DFS_mid(int u,int id){
if(max(sz[u],sz[t[pos].rt]-sz[u])<mini){//寻找中心边
mini=max(sz[u],sz[t[pos].rt]-sz[u]);
mid=id;
}
for(int i=hd[u];i;i=e[i].nxt){
if(i!=(id^) && !del[i]){
DFS_mid(e[i].v,i);
}
}
return;
}
void pushup(int p){//处理编号为rt的中心边
t[p].ans=-;
while(!t[p].q.empty() && (c[t[p].q.top().second]==)) t[p].q.pop();
// printf("rt:%d lc:%d rc:%d\n",p,t[p].lc,t[p].rc);
if(!t[p].lc && !t[p].rc){if(!c[t[p].rt])t[p].ans=;}
else{
int tmp=max(t[t[p].lc].ans,t[t[p].rc].ans);
t[p].ans=max(t[p].ans,tmp);
if(!t[t[p].lc].q.empty() && !t[t[p].rc].q.empty())
t[p].ans=max(t[t[p].lc].q.top().first+t[t[p].rc].q.top().first+t[p].len,t[p].ans);
}
return;
}
void update(int u){
c[u]^=;
if(c[u])
for(int i=tmp[u];i;i=eg[i].nxt){
pushup(eg[i].v);
}
else for(int i=tmp[u];i;i=eg[i].nxt){
t[eg[i].v].q.push(make_pair(eg[i].w,u));
pushup(eg[i].v);
}
}
void divide(int u,int p){//边分治
t[p].rt=u;
pos=p;
DFS_S(u,,);
mid=-;mini=INF;
DFS_mid(u,-);
if(mid>){
del[mid]=;del[mid^]=;
int x=e[mid].v,y=e[mid^].v;//先保存两边的点,否则递归过程中mid变了会导致WA
t[p].len=e[mid].w;
t[p].lc=++tot;
t[p].rc=++tot;
divide(x,t[p].lc);
divide(y,t[p].rc);
}
pushup(p);
}
int main(){
int i,j,u,v,w;
n=read();
mct=*n;
for(i=;i<n;i++){
u=read();v=read();w=read();
add1(u,v,w);add1(v,u,w);
}
mct=;
Rebuild(,);
memset(tmp,,sizeof tmp);//初始化原图
mct=;
tot=;
divide(,tot);
char op[];
m=read();
while(m--){
scanf("%s",op);
if(op[]=='A'){
if(t[].ans>=)
printf("%d\n",t[].ans);
else printf("They have disappeared.\n");
}
else{
w=read();
update(w);
}
}
return ;
}
SPOJ QTREE4 - Query on a tree IV的更多相关文章
- SPOJ QTREE4 - Query on a tree IV 树分治
题意: 给出一棵边带权的树,初始树上所有节点都是白色. 有两种操作: C x,改变节点x的颜色,即白变黑,黑变白 A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为0). 分析: ...
- SPOJ QTREE4 Query on a tree IV ——动态点分治
[题目分析] 同bzoj1095 然后WA掉了. 发现有负权边,只好把rmq的方式改掉. 然后T了. 需要进行底(ka)层(chang)优(shu)化. 然后还是T 下午又交就A了. [代码] #in ...
- SPOJ - QTREE4 Query on a tree IV 边分治
题目传送门 题意:有一棵数,每个节点有颜色,黑色或者白色,树边有边权,现在有2个操作,1修改某个点的颜色, 2询问2个白点的之前的路径权值最大和是多少. 题解: 边分治思路. 1.重构图. 因为边分治 ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- SP2666 QTREE4 - Query on a tree IV(LCT)
题意翻译 你被给定一棵n个点的带边权的树(边权可以为负),点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的权值之和. 一开始所有的点都是白色的. 要求作以下 ...
- SPOJ 375. Query on a tree (树链剖分)
Query on a tree Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Ori ...
- 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 ...
- QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树
Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...
- spoj 375 Query on a tree(树链剖分,线段树)
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Sub ...
随机推荐
- javaweb基础(5)_servlet原理
一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- 删除sqlserver管理器登录信息缓存
在Windows10下测试有效: C:\Users\<user>\AppData\Roaming\Microsoft\Microsoft SQL Server\100\Tools\Shel ...
- bash编程之循环控制:
bash编程之循环控制: for varName in LIST; do 循环体 done while CONDITION; do 循环体 done until CONDITION; do 循 ...
- Codevs3324 新斯诺克
题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄.绿.棕.蓝.粉红. ...
- k8s的flannel网络插件配置
flannel的网络插件配置 Kubernetes网络通信需要解决以下问题: (1)容器间通信:同一个Pod内的多个容器间的通信,lo (2)Pod通信:P ...
- APP客户端图片上传PHP接口
1.客户端 file_get_contents($_FILES['img']['tmp_name']) //获取临时目录下的上传文件流,加密传给接口 2.接口处理端 $img = file_get ...
- nrf528xx bootloader 模块介绍(转载)
转载https://www.cnblogs.com/rfnets/p/8205521.html 1. bootloader 的基本功能: 启动应用 几个应用之间切换 初始化外设 nordic nrf5 ...
- CodeForces 703A Mishka and trip
Description Little Mishka is a great traveller and she visited many countries. After thinking about ...
- Tracer Deployment UVALive - 8271 二分图匹配
复习二分图又想起了这道题,裸的二分图匹配,直接匈牙利算法就可以了,mark一下这个比较好用的稠密图匈牙利算法模板 题目:题目链接 AC代码: #include <iostream> #in ...
- HDU - 4763 Theme Section (KMP的next数组的应用)
给定一个字符串,求出一个前缀A,使得字符串的构成可以表示成ABABA的形式(B可以为空串). 输出这个前缀的最大长度. KMP算法Next数组的使用. 枚举中间的每个位置,可以根据Next数组求出这个 ...