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 ...
随机推荐
- cocos2dx通过ndk编译c++库
ndk编译c++库,然后通过jni调用实现重要代码封装,是安卓应用中最常用的技术,一方面可以将重要的代码实现隐藏,防止泄漏,也可以提高打包速度. ndk里面的sample文件夹中有很多实用的例子,其中 ...
- Voyager的数据库操作与Bread Builder,解决国内打开网速超级慢的问题
Products表的创建: Bread Builder 伟大的XX封了谷哥,所以有关网站实在是打不开,正准备放弃的时候,突然发现问题了,对就是这个网站ajax.googleapis.com,由于调用的 ...
- 如何使用jmeter做接口测试
1.传参:key=value形式 2.传参:json格式 3.jmeter上传文件 4.jmeter传cookie 或者使用 HTTP Cookie管理器
- 《linux设备驱动开发详解》笔记——10中断与时钟
10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...
- 跟踪路由 tracert
由于最近遇到网络出现故障的问题,便使用到Tracert来确定了下出现故障的网络节点 记录下tracert命令相关内容 1. 简介 2. Tracert工作原理... 3. 常用参数 4. 使用示例与输 ...
- 数学基础:HUD1124-Factorial(N!末尾0的个数)
Factorial Problem Description The most important part of a GSM network is so called Base Transceiver ...
- The 2018 ACM-ICPC Chinese Collegiate Programming Contest Moving On
Firdaws and Fatinah are living in a country with nn cities, numbered from 11 to nn.Each city has a r ...
- TypeError: cannot use a string pattern on a bytes-like object
一劳永逸解决:TypeError: cannot use a string pattern on a bytes-like object TypeError: cannot use a string ...
- SPOJ375 Query on a tree(树链剖分)
传送门 题意 给出一棵树,每条边都有权值,有两种操作: 把第p条边的权值改为x 询问x,y路径上的权值最大的边 code #include<cstdio> #include<algo ...
- 加密javascript代码
最近看了个js日历,里面用到了加密,看了下,自己也模仿做加密,现在只能加密一般的javascript语句 <!DOCTYPE html> <html> <meta htt ...