唉,大学军有自己的OJ就是好,无限orz

只有周六的比赛是开放的囧,这场比赛最后因为虚拟机卡住没有及时提交……

否则就能让大家看到我有多弱了……

前两题题解写的很详细,可以自己去看,我来随便扯扯T3好了

题目是这样的:

有一棵以1为根的白黑树,每个节点都是黑色或白色,初始权值是0。维护两个操作:

1.选定一个点a,对于所有黑色的点i,将lca(a,i)的权值加上i; 2.将a号点的颜色反转。

最后求每个点权值

很容易想出这样一个暴力:先考虑1操作,权值增加的点一定是a到根路径上的点

且每个点增加的权值都是自己子树内黑点编号和-路径下一个点的子树内黑点遍和(a增加的就是自己子树内黑点的编号和)

这样不难想到一个用dfs序的O(dlogn)+O(logn)(分别代表两个操作复杂度的做法,d是树的深度)

这样可以跑过深度很小的数据(比如菊花图)

但算法还有很大的优化空间,因为路径上点的操作其实是非常类似的

考虑树链剖分的做法,树链剖分后的复杂度保证是基于这个定理: 任意一点到根的路径所经过的轻边不超过logn

因此,对于操作1经过轻边到达的点以及点a,我们还像之前的做法(子树和-子树和)计算贡献,这样就是O(log^2)

下面考虑重链上的点怎么快速统计,设一段重链为u...p,q...v

当前我们走了一条轻边到了q,进入了一条重链上,则我们要快速处理u...p这一段

任何一个非叶子节点i都在一条重链上,定义重链下一个点叫作重儿子,除此之外点i还延伸出一些轻边,那些轻边延伸到的点我们叫做轻儿子

考虑操作1,在重链上的一点x,如果他的重儿子y及其子树上的黑点会对x产生影响

则操作1的点a一定落在x的轻儿子的子树中,而我们知道,从a这样往上爬,

x一定是通过一条轻边到达的点,根据之前的约定,我们是通过子树直接计算对x的影响的

如果a就是x,那也是通过子树直接计算对x的权值影响的

因此在考虑一段重链u...p上的点x,我们是不用他重儿子的子树对他权值的影响,只要考虑,x的轻儿子子树中的黑点和自身是否是黑点的影响即可:

设w[x]为x轻儿子子树以及自身黑点的编号和,在操作1中,我们只要对一段重链u...p打上+1 tag即可;

相当于每个点x的权值加上了w[x]*tag[x],通过线段树,这样的复杂度也是O(log^2);

如果出现操作2怎么办呢,经过之前的分析就很简单了,我们先维护dfs序的子树和

然后只要顺着a向根走,更新a点以及经过轻边到达的点x(更新w[],计算之前tag带来的影响)就可以了

  1 type node=record
2 po,next:longint;
3 end;
4
5 var e:array[0..400010] of node;
6 top,p,s,fa,d,a,b,c:array[0..200010] of longint;
7 f,w,ans:array[0..200010] of int64;
8 tree:array[0..200010*4] of longint;
9 t,i,n,m,len,x,y:longint;
10
11 function lowbit(x:longint):longint;
12 begin
13 exit(x and (-x));
14 end;
15
16 procedure add(x,y:longint);
17 begin
18 inc(len);
19 e[len].po:=y;
20 e[len].next:=p[x];
21 p[x]:=len;
22 end;
23
24 procedure ins(x,w:longint);
25 begin
26 while x<=n do
27 begin
28 f[x]:=f[x]+w;
29 x:=x+lowbit(x);
30 end;
31 end;
32
33
34 procedure dfs1(x:longint);
35 var i,y:longint;
36 begin
37 s[x]:=1;
38 i:=p[x];
39 while i<>0 do
40 begin
41 y:=e[i].po;
42 if s[y]=0 then
43 begin
44 fa[y]:=x;
45 d[y]:=d[x]+1;
46 dfs1(y);
47 s[x]:=s[x]+s[y];
48 end;
49 i:=e[i].next;
50 end;
51 end;
52
53 procedure dfs2(x:longint);
54 var i,y,q:longint;
55 begin
56 inc(t);
57 b[x]:=t;
58 a[t]:=x;
59 q:=0;
60 i:=p[x];
61 while i<>0 do
62 begin
63 y:=e[i].po;
64 if b[y]=0 then
65 if s[y]>s[q] then q:=y;
66 i:=e[i].next;
67 end;
68 if q<>0 then
69 begin
70 top[q]:=top[x];
71 dfs2(q);
72 end;
73 i:=p[x];
74 while i<>0 do
75 begin
76 y:=e[i].po;
77 if b[y]=0 then
78 begin
79 top[y]:=y;
80 dfs2(y);
81 end;
82 i:=e[i].next;
83 end;
84 end;
85
86 function ask(x:longint):int64;
87 begin
88 ask:=0;
89 while x>0 do
90 begin
91 ask:=ask+f[x];
92 x:=x-lowbit(x);
93 end;
94 end;
95
96 procedure push(i:longint);
97 begin
98 if tree[i]<>0 then
99 begin
100 inc(tree[i*2],tree[i]);
101 inc(tree[i*2+1],tree[i]);
102 tree[i]:=0;
103 end;
104 end;
105
106 procedure get(i,l,r,x:longint);
107 var m:longint;
108 begin
109 if l=r then
110 begin
111 inc(ans[a[l]],w[a[l]]*int64(tree[i]));
112 tree[i]:=0;
113 end
114 else begin
115 m:=(l+r) shr 1;
116 push(i);
117 if x<=m then get(i*2,l,m,x)
118 else get(i*2+1,m+1,r,x);
119 end;
120 end;
121
122 procedure tag(i,l,r,x,y:longint);
123 var m:longint;
124 begin
125 if (x<=l) and (y>=r) then
126 inc(tree[i])
127 else begin
128 m:=(l+r) shr 1;
129 push(i);
130 if x<=m then tag(i*2,l,m,x,y);
131 if y>m then tag(i*2+1,m+1,r,x,y);
132 end;
133 end;
134
135 procedure work(x,z:longint);
136 begin
137 ins(b[x],z);
138 while x<>0 do
139 begin
140 get(1,1,n,b[x]);
141 w[x]:=w[x]+z;
142 x:=fa[top[x]];
143 end;
144 end;
145
146 procedure calc(x:longint);
147 var y:longint;
148 begin
149 y:=0;
150 while x<>0 do
151 begin
152 inc(ans[x],ask(b[x]+s[x]-1)-ask(b[x]-1));
153 if y<>0 then
154 dec(ans[x],ask(b[y]+s[y]-1)-ask(b[y]-1));
155 if x<>top[x] then tag(1,1,n,b[top[x]],b[x]-1);
156 y:=top[x];
157 x:=fa[y];
158 end;
159 end;
160
161 begin
162 readln(n,m);
163 for i:=1 to n do
164 read(c[i]);
165 for i:=1 to n-1 do
166 begin
167 readln(x,y);
168 add(x,y);
169 add(y,x);
170 end;
171 dfs1(1);
172 top[1]:=1;
173 dfs2(1);
174 for i:=1 to n do
175 if c[i]=1 then work(i,i);
176 for i:=1 to m do
177 begin
178 readln(x,y);
179 if x=1 then calc(y)
180 else begin
181 if c[y]=1 then work(y,-y)
182 else work(y,y);
183 c[y]:=1-c[y];
184 end;
185 end;
186 for i:=1 to n do
187 begin
188 get(1,1,n,b[i]);
189 writeln(ans[i]);
190 end;
191 end.

学军NOI训练13 T3 白黑树的更多相关文章

  1. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

  2. 南京邮电大学网络攻防训练平台(NCTF)-异性相吸-Writeup

    南京邮电大学网络攻防训练平台(NCTF)-异性相吸-Writeup 题目描述 文件下载地址 很明显,文件之间进行亦或就可得到flag,不再多说,直接上脚本 #coding:utf-8 file_a = ...

  3. 2019学军集训记&PKUWC2020游记

    题解:https://www.cnblogs.com/gmh77/p/12051260.html 集训(×) 被虐(√) Day1 二段考 Day2 绝对不鸽 没那回事 还在路上 其实就是咕了两天 晚 ...

  4. 小白学 Python 数据分析(13):Pandas (十二)数据表拼接

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  5. 学军NOIP2016模拟赛1

    GTMD这么水的一套题没有AK T1:妥妥的二分答案,贪心check. T2:问题可以转化为最长上升(还是下降我记不住了)子序列. T3:发现点被覆盖上的顺序是一定的.求出这个顺序,第一个操作在线段树 ...

  6. 跟我学系列教程——《13天让你学会Redis》火热报名中

    学习目标 每天2小时,13天让你学会Redis. 本课程针对Redis新手,甚至连Redis是什么都没有听说过的同学.课程会具体介绍Redis是什么以及为什么要使用Redis,结合项目实践旨在让学生从 ...

  7. 小白学 Python 爬虫(13):urllib 基础使用(三)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  8. 从零学React Native之13 持久化存储

    数据持久化就是指应用程序将某些数据存储在手机存储空间中. 借助native存储 这种方式不言而喻,就是把内容传递给native层,通过原生API存储,详见从零学React Native之05混合开发 ...

  9. XJOI网上同步训练DAY5 T3

    就是对于一个数,我们去考虑把t*****减到(t-1)9999*的代价. #include<cstdio> #include<cmath> #include<algori ...

随机推荐

  1. Oracle 多行记录合并/连接/聚合字符串的几种方法

    怎么合并多行记录的字符串,一直是oracle新手喜欢问的SQL问题之一,关于这个问题的帖子我看过不下30个了,现在就对这个问题,进行一个总结.-什么是合并多行字符串(连接字符串)呢,例如: SQL&g ...

  2. 《C++Primer》复习——with C++11 [1]

    1.头文件中不应包含using声明,因为头文件的内容会拷贝到所有引用到他的文件中去,如果头文件里有谋个using声明,那么每个使用了该头文件的文件就会有这个声明,由于不经意间包含了一些名字,反而可能产 ...

  3. java集合类(六)About Queue

    接上篇“java集合类(五)About Map” 终于来到了java集合类的尾声,太兴奋了,不是因为可以休息一阵了,而是因为又到了开启新知识的时刻,大家一起加油打气!!Come on...Fighti ...

  4. Flv 视频格式(转)

    最近要用到flv,整理了一些flv格式的资料,供参考. flv文件主要由两部分组成:header和body. 1.header header部分记录了flv的类型.版本等信息,是flv的开头,一般都差 ...

  5. Azure VM 远程无法登陆问题(No Remote Desktop License)

    解决方法: 打开 Wins+R=> mstsc /v: yourVMIPadress /admin mstsc /v:xx.xx.xx.xx:54738 /admin

  6. c++ 如何实现,readonly

    需求: 我要实现一个常量字段,只能赋值一次,赋值后不容许更改. 类似于c#的readonly或者java final #include <iostream> class  A{public ...

  7. BZOJ3550: [ONTAK2010]Vacation

    3550: [ONTAK2010]Vacation Time Limit: 10 Sec  Memory Limit: 96 MBSubmit: 91  Solved: 71[Submit][Stat ...

  8. 剑指offer--面试题4

    题目:替换字符串中的空格为“%20”. 说明:在浏览器的地址栏中输入某个网址,在解析过程中会看到类似“%20”的字样,这应该就是网络编程涉及的内容... 该题总体来说比较简单(连我都能想到!),个人认 ...

  9. MemSQL Start[c]UP 2.0 - Round 2 - Online Round

    搞到凌晨4点一个没出,要gg了. A. Golden System http://codeforces.com/contest/458/problem/A #include<cstdio> ...

  10. 【.Net--资料】

    1.http://msdn.microsoft.com/zh-cn/dn338450 2..NET Technology Guidance http://www.microsoft.com/net/n ...