传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1095

首先我必须得感谢yzjc的细心讲解和某岛的题解,如果没有的话我相信我现在还在纠结。。不过某岛的上面写的后面我没有看懂,然后yzjc就给我讲了一个可看的合并。不过由于我自己写的比较的丑,在bzoj的跑的还是比较的慢。。。

首先这道题需要转成一个括号序列,然后我们可以发现两个点之间的路径可以通过某种加法得到,假设向下走为+1, 向上走是 -1,并且我们在这个序列中加入原来的点,也就是一个点在序列中会有三个点表示,这个时候发现两点之间的距离是可以分为两段——一段向上的-1的然后一段+1的(一段中出现的可匹配的括号已经合并了),答案就是前段的-1的和的相反数,加上后面的+1的和。 而如果要使值最大,在不考虑点颜色的情况下,那么这个分割点的应该是lca,不过这个不重要,因为需要找到的是一个值最大,lca具体事哪个位置并不重要

那么考虑答案合并的时候,对于一个答案,那么他可以被lson的答案和rson的答案更新,同时还有可能有中间的一段。而中间一段的分割点可能在中间点的左边或者右边。在左边的时候那么就是左边的后缀的最大的答案加上右边最大的前缀和(相当于右边一定是向下的一段) 在右边的时候就是左边后缀最小和的绝对值+右边前缀答案最大值。然后前缀后缀和参照最大字段和,然后最大答案前缀和后缀类似,前缀的话是左边的前缀,左边的全局答案(新的量)+右边的前缀最大和,左边的和的相反数家右边的前缀最大答案。而刚刚提到的全局答案指的是从区间左边到区间右边整个的答案类似全局的和。 而这个更新方式相当于是找个最大值(因为找lca相当于找一个最大值), 参考一下前面的答案合并就好了

不知道说了这么多好像有点乱= = 不过确实他就是这么的乱。 然后考虑颜色,黑点0,白点INF表示不可取,边的前缀答案和后缀答案及其相关量也是INF,因为边不能单独存在而是要必须要黑点最为端点

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f; struct node {
int data, ans, sum, lsum, rsum, lans, rans;
node *l ,*r;
}tr[maxn * ]; int trne = ;
node* root; void test(node* x, int l, int r) {
cout << l <<" "<< r <<" "<< x-> data <<" " << x-> ans <<" "<< x-> sum <<" "<< x-> lsum <<" "<< x-> rsum <<" "<<x-> lans <<" "<< x-> rans <<" "<< endl;
if(l ^ r) {
int mid = (l + r) >> ;
test(x-> l, l, mid), test(x-> r, mid + , r);
}
} node* build(int l, int r) {
node* now = tr + trne ++;
if(l ^ r) {
int mid = (l + r) >> ;
now-> l = build(l, mid);
now-> r = build(mid + , r);
}
return now;
} void update(node *x) {
if(x-> l) {
x-> data = max(max(x-> l-> data, x-> r-> data), max(x-> l-> rans + x-> r-> lsum, -x-> l-> rsum + x-> r-> lans));
x-> ans = max(x-> l-> ans + x-> r-> sum, -x-> l-> sum + x-> r-> ans);
x-> sum = x-> l-> sum + x-> r-> sum;
x-> lsum = max(x-> l-> lsum, x-> l-> sum + x-> r-> lsum);
x-> rsum = min(x-> r-> rsum, x-> r-> sum + x-> l-> rsum);
x-> lans = max((x-> l-> lans), max(x-> l-> ans + x-> r-> lsum, -x-> l-> sum + x-> r-> lans));
x-> rans = max((x-> r-> rans), max(x-> l-> rans + x-> r-> sum, -x-> l-> rsum + x-> r-> ans));
}
} void insert(node* x, int l, int r, int v, int pos, int col) {
if(l == r) {
x-> ans = x-> data = x-> sum = x-> lsum = x-> rsum = x-> lans = x-> rans = ;
x-> data = -INF;
if(!v) {
if(col == ) x-> lsum = -INF, x-> rsum = INF, x-> lans = -INF, x-> rans = -INF, x-> ans = -INF, x-> data = -INF;
}
else {
x-> sum = v; x-> ans = abs(v); x-> data = abs(v);
if(v > ) x-> lsum = -INF, x-> rsum = INF, x-> lans = x-> rans = -INF, x-> data = -INF, x-> ans = ;
else x-> rsum = INF, x-> lsum = -INF, x-> lans = x-> rans = -INF, x-> data = -INF, x-> ans = ;
}
}
else {
int mid = (l + r) >> ;
if(pos <= mid) insert(x-> l, l, mid, v, pos, col);
else insert(x-> r, mid + , r, v, pos, col);
update(x);
}
} struct edge {
int t; edge* next;
}e[maxn * ], *head[maxn]; int ne = ; void addedge(int f, int t) {
e[ne].t = t, e[ne].next = head[f], head[f] = e + ne ++;
} int in[maxn], map[maxn], out[maxn], c[maxn], num = , n, m;
int cnt = ; void dfs(int x, int fa) {
in[x] = num ++, map[x] = num ++;
for(edge* p = head[x]; p; p = p-> next) {
if(p-> t != fa) dfs(p-> t, x);
}
out[x] = num ++;
} int int_get() {
int x = ; char c = (char)getchar();
while(!isdigit(c) && c != '-') c = (char)getchar();
bool f = ;
if(c == '-') c = (char)getchar(), f = ;
while(isdigit(c)) {
x = x * + (int)(c - '');
c = (char)getchar();
}
if(f) x = -x;
return x;
} void read() {
n = int_get(); cnt = n;
for(int i = ; i < n; ++ i) {
int u, v; u = int_get(), v = int_get();
addedge(u, v), addedge(v, u);
}
for(int i = ; i <= n; ++ i) c[i] = ;
dfs(, ); num -= ; root = build(, num);
for(int i = ; i <= n; ++ i) {
insert(root, , num, , map[i], c[i]);
if(i != ) {
insert(root, , num, , in[i], );
insert(root, , num, -, out[i], );
}
}
} void sov() {
m = int_get();
while(m --) {
char s[]; scanf("%s", s + );
if(s[] == 'G') {
if(cnt <= ) printf("%d\n", cnt - );
else printf("%d\n", root-> data);
}
if(s[] == 'C') {
int x = int_get();
if(c[x]) cnt --;
else cnt ++;
c[x] = !c[x];
insert(root, , num, , in[x], );
insert(root, , num, , map[x], c[x]);
insert(root, , num, -, out[x], );
}
}
//test(root, 1, num); cout << endl;
} int main() {
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
read(); sov();
//update(root-> r);
return ;
}

bzoj 1095的更多相关文章

  1. bzoj 1095 Hide 捉迷藏 - 动态点分治 -堆

    Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双 ...

  2. BZOJ 1095: [ZJOI2007]Hide 捉迷藏

    Description 一棵树,支持两个操作,修改一个点的颜色,问树上最远的两个白点距离. Sol 动态点分治. 动态点分治就是将每个重心连接起来,形成一个跟线段树类似的结构,当然它不是二叉的... ...

  3. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  4. BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)

    BZOJ 洛谷 对树DFS得到括号序列.比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]. 那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[] ...

  5. bzoj 1095 括号序列求两点距离

    大致题意: 给一棵树,每个节点最开始都是黑色,有两种操作,1.询问树中相距最远的一对黑点的距离 2.反转一个节点的颜色 一种做法: 建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n ...

  6. 【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)

    1095: [ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏 ...

  7. BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)

    这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...

  8. [BZOJ]1095 Hide捉迷藏(ZJOI2007)

    一道神题,两种神做法. Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特 ...

  9. 【bzoj 1095】[ZJOI2007]Hide 捉迷藏

    题目链接: TP 题解: 样例好良心,调样例3h一A…… 细节好多……诸如没完没了的pop和push……搞得头都大了. 同情zzh……调了整一天了. 动态点分治裸题……果然每个“裸题”打起来都跟shi ...

随机推荐

  1. Java实现按汉语拼音的排序

    public class sortByPinyin { public static void main(String[] args) { String[] arr = { "刘刘" ...

  2. python 标准模块和第三方模块

    >>> help('modules') Please wait a moment while I gather a list of all available modules... ...

  3. 建立logback.xml 配合MDC 实现追踪

    <?xml version="1.0" encoding="UTF-8"?> <configuration debug="false ...

  4. 58、salesforce学习笔记(五)

    Set集合 Set<String> set1 = new Set<String>(); set1.add('1'); set1.add('2'); Set<String& ...

  5. Tomcat负载均衡、调优核心应用进阶学习笔记(二):Tomcat前世今生、安装、配置文件详细说明、tomcat应用程序部署、webapp 体系结构、tomcat运行方式

    文章目录 Tomcat前世今生 安装 配置文件详细说明 tomcat应用程序部署 webapp 体系结构 tomcat运行方式 Tomcat前世今生 java体系: 1 java程序设计语言 2 ja ...

  6. 树状数据删除(TP5)

    应用场景:类似上图中树状菜单,选中一级菜单 点击上方删除按钮 所有子菜单删除 以下是代码截图(代码基于 TP5)

  7. JavaScript中 函数的创建和调用

    基础概念:定义函数的方式   一般定义函数有两种方式:    1:函数的声明    2:函数表达式 参考资料:https://blog.csdn.net/xixiruyiruyi/article/de ...

  8. 使用vue-cli3时怎么mock数据

    应用场景 在前后端分离的开发模式中,后端给前端提供一个接口,由前端向后端发请求,得到数据后前端进行渲染. 由于前后端开发进度的不统一,前端往往使用本地的测试数据进行数据渲染的测试. 如何配置 在vue ...

  9. Cocos2d-x之Scene

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. Scene场景也是cocos2dx中必不可少的元素,游戏中通常我们需要构建不同的场景(至少一个),游戏里关卡.版块的切换也就是一个一个场景 ...

  10. css篇-简化版

    [CSS篇]简化版 (1)     CSS盒模型 CSS盒模型 题目:谈谈你对CSS盒模型的认识 1)       基本概念:标准模型+IE模型 2)       标准模型和IE模型的区别 计算宽度和 ...