[hdu6973]Bookshop
将询问拆成$x$到$lca$和$lca$($lca$靠近$y$的儿子)到$y$两部分,分别处理(后者以前者的答案为基础)
两者是类似地,不妨仅考虑前者:用树剖将该询问拆成dfs序上若干个区间,考虑从后往前遍历dfs序(显然即从下到上),若当前位置被覆盖则执行该节点的操作
进一步的,考虑将一个位置上的操作对覆盖其的位置批量处理,即将问题离线并维护一棵平衡树,仍从后往前遍历dfs序,并支持:
1.(在区间右端点时)加入一个数
2.将当前平衡树中大于等于$k$的数都减去$k$
3.(在区间左端点时)删除一个数
前两个容易处理(删除可以将下标定为询问编号),对于第三个,对权值分类讨论:
1.权值在$[0,k)$中的数不需要处理
2.权值在$[k,2k)$中的数,每一个数至多经历$o(\log V)$次此操作即会变为0(之后显然就不会被操作了),将这些数取出后再暴力操作,复杂度为$o(q\log n\log V)$
3.权值在$[2k,\infty)$中的数,打懒标记即可(第2类需要暴力处理因为要考虑与$[0,k)$中的数的排名)
总复杂度即$o(n\log ^{2}n)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define pii pair<int,int>
5 #define mp make_pair
6 #define fi first
7 #define se second
8 #define s(p) f[k].ch[p]
9 vector<int>v,va[N],vd[N];
10 vector<pii>v0[N],v1[N];
11 int E,rt,t,n,q,x,y,head[N],a[N],st[N],fa[N],sz[N],mx[N],dep[N],dfn[N],idfn[N],top[N];
12 struct Edge{
13 int nex,to;
14 }edge[N<<1];
15 struct Data{
16 int fa,val,mx,mn,tag,ch[2];
17 }f[N];
18 void add_edge(int x,int y){
19 edge[E].nex=head[x];
20 edge[E].to=y;
21 head[x]=E++;
22 }
23 void dfs1(int k,int f,int s){
24 fa[k]=f,sz[k]=1,mx[k]=0,dep[k]=s;
25 for(int i=head[k];i!=-1;i=edge[i].nex)
26 if (edge[i].to!=f){
27 dfs1(edge[i].to,k,s+1);
28 sz[k]+=sz[edge[i].to];
29 if (sz[mx[k]]<sz[edge[i].to])mx[k]=edge[i].to;
30 }
31 }
32 void dfs2(int k,int fa,int t){
33 dfn[k]=++dfn[0],idfn[dfn[0]]=k,top[k]=t;
34 if (mx[k])dfs2(mx[k],k,t);
35 for(int i=head[k];i!=-1;i=edge[i].nex)
36 if ((edge[i].to!=fa)&&(edge[i].to!=mx[k]))dfs2(edge[i].to,k,edge[i].to);
37 }
38 int check(int k){
39 return f[f[k].fa].ch[1]==k;
40 }
41 bool cmp(int x,int y){
42 return (f[x].val<f[y].val)||(f[x].val==f[y].val)&&(x<y);
43 }
44 void upd(int k,int x){
45 f[k].val+=x,f[k].mx+=x,f[k].mn+=x,f[k].tag+=x;
46 }
47 void up(int k){
48 f[k].mx=max(max(f[s(0)].mx,f[s(1)].mx),f[k].val);
49 f[k].mn=min(min(f[s(0)].mn,f[s(1)].mn),f[k].val);
50 }
51 void down(int k){
52 if (s(0))upd(s(0),f[k].tag);
53 if (s(1))upd(s(1),f[k].tag);
54 f[k].tag=0;
55 }
56 void rotate(int k){
57 int F=f[k].fa,G=f[F].fa,p=check(k);
58 f[k].fa=G;
59 if (G)f[G].ch[check(F)]=k;
60 f[s(p^1)].fa=F,f[F].ch[p]=s(p^1);
61 f[F].fa=k,s(p^1)=F;
62 up(F),up(k);
63 }
64 void clear(int k){
65 for(int i=k;i;i=f[i].fa)st[++st[0]]=i;
66 while (st[0])down(st[st[0]--]);
67 }
68 void splay(int k,int fa){
69 clear(k);
70 for(int i=f[k].fa;i!=fa;i=f[k].fa){
71 if (f[i].fa!=fa){
72 if (check(i)==check(k))rotate(i);
73 else rotate(k);
74 }
75 rotate(k);
76 }
77 if (!fa)rt=k;
78 }
79 void get_val(int k){
80 if (!k)return;
81 v.push_back(k);
82 get_val(s(0));
83 get_val(s(1));
84 }
85 int find_pre(int k,int x){
86 if (!k)return 0;
87 down(k);
88 if (!cmp(k,x))return find_pre(s(0),x);
89 int ans=find_pre(s(1),x);
90 if (ans)return ans;
91 return k;
92 }
93 int find_nex(int k,int x){
94 if (!k)return 0;
95 down(k);
96 if (!cmp(x,k))return find_nex(s(1),x);
97 int ans=find_nex(s(0),x);
98 if (ans)return ans;
99 return k;
100 }
101 void add(int k){
102 clear(k);
103 int l=find_pre(rt,k),r=find_nex(rt,k);
104 if (!l){
105 if (!r)rt=k;
106 else{
107 splay(r,0);
108 f[k].fa=rt,f[rt].ch[0]=k;
109 up(rt);
110 }
111 }
112 else{
113 splay(l,0);
114 if (!r){
115 f[k].fa=rt,f[rt].ch[1]=k;
116 up(rt);
117 }
118 else{
119 splay(r,rt);
120 f[k].fa=f[rt].ch[1],f[f[rt].ch[1]].ch[0]=k;
121 up(f[rt].ch[1]),up(rt);
122 }
123 }
124 }
125 void dec(int k){
126 clear(k);
127 int l=find_pre(rt,k),r=find_nex(rt,k);
128 if (!l){
129 if (!r)rt=0;
130 else{
131 splay(r,0);
132 f[rt].ch[0]=0;
133 up(rt);
134 }
135 }
136 else{
137 splay(l,0);
138 if (!r){
139 f[rt].ch[1]=0;
140 up(rt);
141 }
142 else{
143 splay(r,rt);
144 f[f[rt].ch[1]].ch[0]=0;
145 up(f[rt].ch[1]),up(rt);
146 }
147 }
148 f[k].fa=0;
149 }
150 void update_force(int x,int y,int z){
151 v.clear();
152 f[0].val=x,f[q+1].val=y;
153 int l=find_pre(rt,0),r=find_nex(rt,q+1);
154 if (!l){
155 if (!r)get_val(rt);
156 else{
157 splay(r,0);
158 get_val(f[rt].ch[0]);
159 up(rt);
160 }
161 }
162 else{
163 splay(l,0);
164 if (!r){
165 get_val(f[rt].ch[1]);
166 up(rt);
167 }
168 else{
169 splay(r,rt);
170 get_val(f[f[rt].ch[1]].ch[0]);
171 up(f[rt].ch[1]),up(rt);
172 }
173 }
174 for(int i=0;i<v.size();i++){
175 dec(v[i]);
176 f[v[i]].val+=z;
177 add(v[i]);
178 }
179 }
180 void update_tag(int x,int y,int z){
181 f[0].val=x,f[q+1].val=y;
182 int l=find_pre(rt,0),r=find_nex(rt,q+1);
183 if (!l){
184 if (!r)upd(rt,z);
185 else{
186 splay(r,0);
187 upd(f[rt].ch[0],z);
188 up(rt);
189 }
190 }
191 else{
192 splay(l,0);
193 if (!r){
194 upd(f[rt].ch[1],z);
195 up(rt);
196 }
197 else{
198 splay(r,rt);
199 upd(f[f[rt].ch[1]].ch[0],z);
200 up(f[rt].ch[1]),up(rt);
201 }
202 }
203 }
204 int main(){
205 f[0].mn=0x3f3f3f3f;
206 scanf("%d",&t);
207 while (t--){
208 scanf("%d%d",&n,&q);
209 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
210 E=dfn[0]=0;
211 for(int i=1;i<=n;i++)head[i]=-1;
212 for(int i=1;i<n;i++){
213 scanf("%d%d",&x,&y);
214 add_edge(x,y);
215 add_edge(y,x);
216 }
217 dfs1(1,0,0);
218 dfs2(1,0,1);
219 for(int i=1;i<=q;i++){
220 scanf("%d%d%d",&x,&y,&f[i].val);
221 v0[i].clear(),v1[i].clear();
222 while (top[x]!=top[y]){
223 if (dep[top[x]]>dep[top[y]]){
224 v0[i].push_back(mp(dfn[x],dfn[top[x]]));
225 x=fa[top[x]];
226 }
227 else{
228 v1[i].push_back(mp(dfn[top[y]],dfn[y]));
229 y=fa[top[y]];
230 }
231 }
232 if (dfn[x]>dfn[y])v0[i].push_back(mp(dfn[x],dfn[y]));
233 else v1[i].push_back(mp(dfn[x],dfn[y]));
234 }
235 for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear();
236 for(int i=1;i<=q;i++)
237 for(int j=0;j<v0[i].size();j++){
238 va[v0[i][j].fi].push_back(i);
239 vd[v0[i][j].se].push_back(i);
240 }
241 rt=0;
242 for(int i=1;i<=q;i++){
243 f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0;
244 f[i].mx=f[i].mn=f[i].val;
245 }
246 for(int i=n;i;i--){
247 int k=a[idfn[i]];
248 for(int j=0;j<va[i].size();j++)add(va[i][j]);
249 update_force(k,(k<<1)-1,-k);
250 update_tag((k<<1),1e9,-k);
251 for(int j=0;j<vd[i].size();j++)dec(vd[i][j]);
252 }
253 for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear();
254 for(int i=1;i<=q;i++)
255 for(int j=0;j<v1[i].size();j++){
256 va[v1[i][j].fi].push_back(i);
257 vd[v1[i][j].se].push_back(i);
258 }
259 rt=0;
260 for(int i=1;i<=q;i++){
261 f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0;
262 f[i].mx=f[i].mn=f[i].val;
263 }
264 for(int i=1;i<=n;i++){
265 int k=a[idfn[i]];
266 for(int j=0;j<va[i].size();j++)add(va[i][j]);
267 update_force(k,(k<<1)-1,-k);
268 update_tag((k<<1),1e9,-k);
269 for(int j=0;j<vd[i].size();j++)dec(vd[i][j]);
270 }
271 for(int i=1;i<=q;i++)printf("%d\n",f[i].val);
272 }
273 return 0;
274 }
[hdu6973]Bookshop的更多相关文章
- Bookshop(一)数据库连接
连接池配置文件db.properties配置 1.新建一个普通文件->改名为db.properties(后缀)手动添加属性 一般为数据库驱动类.数据库连接地址.用户名.用户密码 driver=c ...
- java.lang.ClassCastException: xut.bookshop.entity.User_$$_javassist_3 cannot be cast to javassist.util.proxy.Proxy
报错信息 java.lang.ClassCastException: xut.bookshop.entity.User_$$_javassist_3 cannot be cast to javassi ...
- jQuery +ajax +json+实现分页
正文 首先我们创建一般处理程序,来读取数据库中内容,得到返回值. 创建文件,GetData.ashx. 我这里是用的存储过程,存储过程会再下面粘出来,至于数据只是实例,你们可根据需求自行读取数据 代码 ...
- 达梦7的试用 与SQLSERVER的简单技术对比
达梦7的试用 与SQLSERVER的简单技术对比 达梦数据库公司推出了他们的数据库服务管理平台,可以在该平台使用达梦数据库而无须安装达梦7数据库 地址:http://online.dameng.com ...
- [ASP.NET MVC 小牛之路]05 - 使用 Ninject
在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事情,续这篇文章之后,本文将用一个实际的示例来 ...
- [ASP.NET MVC 小牛之路]06 - 使用 Entity Framework
在家闲着也是闲着,继续写我的[ASP.NET MVC 小牛之路]系列吧.在该系列的上一篇博文中,在显示书本信息列表的时候,我们是在程序代码中手工造的数据.本文将演示如何在ASP.NET MVC中使用E ...
- 微冷的雨ASP.NET MVC之葵花宝典(MVC)
微冷的雨ASP.NET MVC之葵花宝典 By:微冷的雨 第一章 ASP.NET MVC的请求和处理机制. 在MVC中: 01.所有的请求都要归结到控制器(Controller)上. 02.约定优于配 ...
- spring aop注解配置
spring aop是面向切面编程,使用了动态代理的技术,这样可以使业务逻辑的代码不掺入其他乱七八糟的代码 可以在切面上实现合法性校验.权限检验.日志记录... spring aop 用的多的有两种配 ...
- vs.net Web.csproj.webinfo文件
使用VS工具打开工程的时候,请直接打开BookShop.sln文件, 请修改WEB/Web.csproj.webinfo文件中的<Web URLPath = "http://local ...
随机推荐
- 宝塔Linux面板搭建与安全狗安装(WEB服务器搭建与WAF安装)
环境 系统:CentOS 7.3 (64位) 软件: 宝塔Linux 7.7 网站安全狗Linux-Apache版V2.3.18809(64位) 宝塔面板 下载和安装 网址:https://www.b ...
- Space Time Pattern Mining Tools(时空模式挖掘工具)
时空模式挖掘工具 # Process: 局部异常值分析 arcpy.LocalOutlierAnalysis_stpm("", "", 输出要素, " ...
- md5验证文件上传,确保信息传输完整一致
注:因为是公司项目,仅记录方法和思路以及可公开的代码. 最近在公司的项目中,需要实现一个上传升级包到服务器的功能: 在往服务器发送文件的时候,需要确保 文件从开始发送,到存入服务器磁盘的整个传输的过程 ...
- Pytorch 实现简单线性回归
Pytorch 实现简单线性回归 问题描述: 使用 pytorch 实现一个简单的线性回归. 受教育年薪与收入数据集 单变量线性回归 单变量线性回归算法(比如,$x$ 代表学历,$f(x)$ 代表收入 ...
- Java(43)JDK新特性之方法引用
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228461.html 博客主页:https://www.cnblogs.com/testero ...
- javascript-jquery介绍
jquery优势 1.轻量级 2.强大的选择器 3.出色的DOM封装 4.可靠的事件处理机制 5.完善的Ajax 6.不污染顶级变量 7.出色的浏览器兼容 8.链式操作方式 9.隐式迭代 10.行为层 ...
- 分享一份软件测试项目实战(web+app+h5+小程序)
大家好,我是谭叔. 本次,谭叔再度出马,给大家找了一个非常适合练手的软件测试项目,此项目涵盖web端.app端.h5端.小程序端,可以说非常之全面. 缘起 在这之前,谭叔已经推出了九套实战教程. 但是 ...
- SpringCloud 2020.0.4 系列之服务降级的其他用法与熔断
1. 概述 老话说的好:控制好自己的情绪,才能控制好自己的人生.冲动是魔鬼,冷静才最重要. 言归正传,之前聊了在 Feign 调用时,如何给整个 Feign接口类 增加降级策略. 今天我们来聊一下 H ...
- 2021.8.6考试总结[NOIP模拟32]
T1 smooth 考场上水个了优先队列多带个$log$,前$80$分的点跑的飞快,后面直接萎了. 其实只需开$B$个队列,每次向对应队列中插入新的光滑数,就能保证队列中的数是单调的. 为了保证不重, ...
- Machine learning (8-Neural Networks: Representation)
1.Non-linear Hypotheses 2.Neurons and the Brain 从某种意义上来说,如果我们能找出大脑的学习算法,然后在计算机上执行大脑学习算法或与之相似的算法,也许这将 ...