传送门: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. postgres服务之加密

    数据中往往会出现一些敏感字段,例如电话,邮箱等,这时候有需求进行加密保存 目前可以实现的方式有两种 方式一:这种方法,aes的加密方法不支持aes-192,不支持aes-256 #使用encrypt加 ...

  2. 由于阿里云磁盘空间导致hadoop的yarn节点处于UNHEALTHY状态

    最初使用的阿里云云盘只有50G 正常运行的hadoop集群突然无法正常运行了,web页面显示节点为UNHEALTHY 使用df -m命令,发现一些节点磁盘空间占用达到了99%,因此要扩容磁盘空间 1. ...

  3. ActiveMQ消息中间件Producer和Consumer

    ActiveMQ消息中间件Producer和Consumer 原创jethai2015-08-18 18:08:56评论(0)1480人阅读   生产者代码: 1 2 3 4 5 6 7 8 9 10 ...

  4. USB驱动程序设计

    1.USB驱动模型 ①USB HOST控制器驱动 ②USBhexin ③USB客户端驱动 设备4个层次:设备(device).配置(Config).接口(Interface).端点(Endpoint) ...

  5. paper 144:人生苦短,快用Python

    1.Python 语言特点 Python是一种面向对象.直译式计算机程序设计语言,这种语言的语法简捷而清晰,具有丰富和强大的类库,基本上能胜任你平时需要的编程工作. Python的优点: (1)编写的 ...

  6. Django基础篇(二)与mysql配合使用

    需求:模拟实现学员管理系统.<*_* 从基础做起> 表结构如下: 班级/学生/老师 班级表: id     title 1       xx 2 xx 学生表: id    name    ...

  7. DPL, CPL及RPL之间的关系

    DPL: Descriptor Privilege Level 1) GDT/LDT表中的描述符 GDT/LDT表中的描述符,描述的是一段内存. 其中的DPL代表着GDT/LDT中的描述符描述的内存段 ...

  8. Process Hacker源码中的用户态hook的做法

    processhacker-code-5632\1.x\trunk\NProcessHacker\hook.h typedef struct _PH_HOOK { PVOID Function; PV ...

  9. centos为用户添加sudo功能

    su chmod a+w /etc/sudoers vim /etc/sudoers [找到root ALL=(ALL) ALL这行] 复制出新的一行,并且将root改为daniel(当前用户名) c ...

  10. Git与GitHub同步

    如何通过Git Bash实现本地与远端仓库——GitHub的同步 1.下载安装Git:下载网址 2.在自己的github上新建一个repository 例如我这里新建了一个叫test的reposito ...