传送门: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. comet4j js中写法

    <script type="text/javascript" src="${ctxStatic}/common/js/comet4j.js">< ...

  2. Echarts 甘特图教程

    Echarts甘特图教程  echarts官网实例: https://gallery.echartsjs.com/editor.html?c=xEYpsVs30s 效果:  代码: <html& ...

  3. VC连接SQLite3的方法(MFC封装类)

    SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,支持跨平台,操作简单,能够使用很多语言直接创建数据库.官方网站:www.sqlite.org 在VC环境下编写连接SQLite的 ...

  4. [CSP-S模拟测试]:E(贪心)

    题目传送门(内部题48) 输入格式 第一行一个整数$n$.接下来$n$行每行两个整数$x_i,y_i$. 输出格式 一行一个整数表示答案. 样例 样例输入$1$: 23 72 5 样例输出$1$: 样 ...

  5. JQ-jQuery-Ajax:jQuery Ajax 操作函数

    ylbtech-JQ-jQuery-Ajax:jQuery Ajax 操作函数 1.返回顶部 1. jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允 ...

  6. cs224d 作业 problem set2 (一) 用tensorflow纯手写实现sofmax 函数,线性判别分析,命名实体识别

    Hi Dear Today we will use tensorflow to implement the softmax regression and linear classifier algor ...

  7. Linux监控cpu,内存,磁盘脚本

    #!/bin/bash # CPU_us=$(vmstat | awk '{print $13}' | sed -n '$p') CPU_sy=$(vmstat | awk '{print $14}' ...

  8. Could not open lock file/var/lib/dpkg/lock的解决

    Could not open lock file/var/lib/dpkg/lock的解决 在ubuntu系统中利用apt-get install something的时候,有时候会出现无法获得锁的权 ...

  9. Kafka启动报错

    文章目录 问题 解决 问题 通过 ./kafka-server-start.sh ../config/server.properties 启动kafka 之前在server.properties中修改 ...

  10. vue父组件与子组件之间的数据传递

    父组件向子组件传递数据 父组件用数据绑定:子组件用props接收 <!-- test-vue-model父组件 --> <template> <div> <m ...