唉,大学军有自己的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. GitHub error “Failed to get HEAD”

    cd /要提交的文件的文件夹下    比如要提交一个名为  demo的  程序, 那么先进入demo 的文件夹里面  然后  进行以下两步 git init  (有时这个是不必要的,因为xcode 自 ...

  2. [搜片神器]服务器SQL2005查询分页语句你理解了么

    在sosobt.com网站准备采用Lucence.net来进行索引处理搜索慢问题的时候,突然发现常用的分页获取数据的row_number也支持不住了,后期查到200多万的时候非常慢(总数据有500万) ...

  3. 用户 IIS APPPOOL\DefaultAppPool 登录失败的解决方法

    解决方案  1.先查看你的网站使用的是哪个应用程序池 2.设置应用程序池的选项 3.标识选项 选LocalSystem或NetworkService就可以解决问题

  4. [原]android不支持命名的semaphore

    之前sem_open在iOS上, 创建命名的semaphore没有问题 (iOS不支持匿名的semaphore), 但是现在Android平台的sem_open时候报错,返回ENOSYS. 命名的se ...

  5. PHP之set_error_handler()函数讲解

    定义和用法 set_error_handler() 函数设置用户自定义的错误处理函数. 该函数用于创建运行时期间的用户自己的错误处理方法. 该函数会返回旧的错误处理程序,若失败,则返回 null. 语 ...

  6. java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@450b2f48 异常处理

    晕死的错误,改了半天也没想到是这样的原因,基础正要呀... 先看一下警告信息: 07-07 08:32:19.540: WARN/WindowManager(74): Failed looking u ...

  7. 利用vim阅读源代码一个好用的工具

    阅读源代码时常常遇到找变量,函数定义的问题.vim为我们提供了一个好用的工具,ctags. 安装 ctags. 在 libvirt的源代码根目录运行 ctags -R . vim -t virConn ...

  8. Installing Lua in Mac

    Lua is distributed in source form. You need to build it before using it. Building Lua should be stra ...

  9. What is the difference between supervised learning and unsupervised learning?

    Machine Learning is a class of algorithms which is data-driven, i.e. unlike "normal" algor ...

  10. POJ 1781

    #include <iostream> #include <string> #include <cmath> using namespace std; unsign ...