[BZOJ3159] 决战 题解
个人感觉各方面难度高于《在美妙的数学王国中畅游》,也不知道是不是求导的关系,这题 \(luogu\) 难度评级还更低。不过感觉这题作完对 \(LCT\) 理解更顺畅了。
前四个操作简单,关键在第五人格操作。
注意力惊人的注意到我们无法像普通 \(Splay\) 一样,直接对 \(LCT\) 中的 \(Splay\) 进行区间反转。因为 \(LCT\) 中的 \(Splay\) 同时维护树的形态 \(id\) 和权值 \(val\)。
那我们干脆把这俩玩意分别处理,相当于建 \(id\ tree\) 和 \(val\ tree\)。由于 \(Splay\) 的操作都是在根处进行,所以我们只需要对于每个根节点 \(rt\) 记录 \(pos_{rt}\) 表示对应另一棵树中自己的编号,就可以完成查询。小改 \(rotate,link\),魔改 \(access\),再加一个 \(setpos\) 用来找 \(pos_{rt}\) 即可。
时间复杂度 \(O(n\log n)\)。
#include<bits/stdc++.h>
#define ll long long
#define fa(x) lct[x].fa
#define fl(x) lct[x].fl
#define mx(x) lct[x].mx
#define mn(x) lct[x].mn
#define sz(x) lct[x].sz
#define ad(x) lct[x].ad
#define val(x) lct[x].val
#define sum(x) lct[x].sum
#define sn(x,i) lct[x].sn[i]
using namespace std;
const int N=1e5+5;
struct node{
int sn[2],val;ll sum;
int mx,mn,fa,fl,sz,ad;
}lct[N];int n,m,tp,st[N];
int pos[N],flg;string s;
int check(int x){
return sn(fa(x),0)!=x&&sn(fa(x),1)!=x;
}int chksn(int x){
return sn(fa(x),1)==x;
}void push_up(int x){
sz(x)=sz(sn(x,0))+sz(sn(x,1))+1;
sum(x)=sum(sn(x,0))+sum(sn(x,1))+val(x);
mx(x)=max({mx(sn(x,0)),mx(sn(x,1)),val(x)});
mn(x)=min({mn(sn(x,0)),mn(sn(x,1)),val(x)});
}void push(int x){
if(!x) return;fl(x)^=1;
swap(sn(x,0),sn(x,1));
}void down(int x,int a){
if(!x) return;
sum(x)+=(ll)sz(x)*a,val(x)+=a;
ad(x)+=a,mx(x)+=a,mn(x)+=a;
}void push_down(int x){
if(!x) return;
if(fl(x)){
push(sn(x,0));
push(sn(x,1));
}down(sn(x,0),ad(x));
down(sn(x,1),ad(x));
fl(x)=ad(x)=0;
}void rotate(int x){
int y=fa(x),z=fa(y),k=chksn(x);
if(check(y)) pos[x]=pos[y];
else sn(z,chksn(y))=x;
fa(x)=z,fa(y)=x,fa(sn(x,1-k))=y;
sn(y,k)=sn(x,1-k),sn(x,1-k)=y;
push_up(y);
}void splay(int x){
st[tp=1]=x;
for(int i=x;!check(i);i=fa(i)) st[++tp]=fa(i);
while(tp) push_down(st[tp--]);
while(!check(x)){
int y=fa(x),z=fa(y);
if(!check(y))
rotate(chksn(x)!=chksn(y)?x:y);
rotate(x);
}push_up(x);
}int find(int x,int k){
push_down(x);
if(sz(sn(x,0))+1==k) return x;
if(sz(sn(x,0))>=k) return find(sn(x,0),k);
return find(sn(x,1),k-sz(sn(x,0))-1);
}void setpos(int x){
splay(x),splay(pos[x]);
pos[x]=find(pos[x],sz(sn(x,0))+1);
splay(pos[x]);
}void access(int x){
setpos(x);int y=sn(x,1),z=sn(pos[x],1);
pos[y]=z,fa(z)=0,sn(x,1)=sn(pos[x],1)=0;
push_up(x),push_up(pos[x]);
while(fa(x)){
setpos(x),setpos(fa(x));
pos[sn(fa(x),1)]=sn(pos[fa(x)],1);
sn(fa(x),1)=x,fa(sn(pos[fa(x)],1))=0;
sn(pos[fa(x)],1)=pos[x];
fa(pos[x])=pos[fa(x)];
push_up(pos[fa(x)]);
push_up(fa(x)),x=fa(x);
}
}void mk(int x){
access(x),setpos(x);
push(x),push(pos[x]);
}void split(int x,int y){
mk(x),access(y),setpos(y);
}void link(int x,int y){
mk(x),setpos(y),fa(x)=y;
}signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
mn(0)=1e18,cin>>n>>m>>tp;
for(int i=1;i<=n;i++)
sz(i)=sz(i+n)=1,pos[i]=i+n,pos[i+n]=i;
for(int i=1,x,y;i<n;i++)
cin>>x>>y,link(x,y);
while(m--){
int x,y,w;cin>>s>>x>>y;split(x,y);
if(s=="Increase") cin>>w,down(pos[y],w);
if(s=="Sum") cout<<sum(pos[y])<<"\n";
if(s=="Major") cout<<mx(pos[y])<<"\n";
if(s=="Minor") cout<<mn(pos[y])<<"\n";
if(s=="Invert") push(pos[y]);
}return 0;
}
[BZOJ3159] 决战 题解的更多相关文章
- BZOJ3159: 决战
方法很简单,树剖,把区间提取出来,打翻转标记,再放回去. 注意:由于某种原因,我写的是把题目中的r忽略掉的一般情况,否则简单得多. 本来以为写起来也很简单T_T #include<bits/st ...
- BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)
题目描述 输入 第一行有三个整数N.M和R,分别表示树的节点数.指令和询问总数,以及X国的据点. 接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路. 接下来M行,每行描述一个指令或 ...
- bzoj3159决战 码农题 树剖套splay
最近沉迷码农题无法自拔 首先有一个暴力的想法:对于每个重链维护一个splay,需要翻转的连起来,翻转,接回去 然后发现这样没问题... 一条链只能跨log个重链,也就只有log个splay的子树参与重 ...
- BZOJ3159: 决战(FHQ Treap)
传送门: 解题思路: 算是补坑了,这题除了Invert以外就可以树剖线段树解决了. 考虑Invert操作,延续先前树链剖分的做法,考虑先前算法的瓶颈. 最暴力的方法是暴力交换权值,然而这种方法忽略了当 ...
- 2017-12 CDQZ集训(已完结)
从联赛活了下来(虽然分数倒一……),接下来要去CDQZ集训啦…… DAY -2 2017-12-16 被老师安排负责一部分同学的住宿以及安排…… 抓紧时间继续学习,LCT真好玩啊真好玩…… 晚上放假了 ...
- CDQZ集训DAY2 日记
依然很爆炸. T1上来有50分暴力分,打完后注意到了后50分的随机数据,开始想怎么去对付他.然后就开始思考随机数据意味着什么.想了想,想打一个扫描线或者分治.决策了一下还是打了一个扫描线+链表.然而只 ...
- 2013 CSU校队选拔赛(1) 部分题解
A: Decimal Time Limit: 1 Sec Memory Limit: 128 MB Submit: 99 Solved: 10 [ Submit][ Status][ Web ...
- ypACM社团年终赛暨实验室选拔赛题解
记得补题,题目两小时半还是挺困难ak的,毕竟我验题也验了几天的时间,题目基本没有锅.题目基本属于简单题 我的三道题都是很基本的题目,希望大家补题 这些题解都是我写的,如果有疑问可以qq问我 所有的核心 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
随机推荐
- Java框架 —— MyBatis
MyBatis 简介 持久层框架,半自动映射,支持自定义SQL.高级映射.存储过程,免除了JDBC代码.参数设置.获取结果集的工 作,可以通过XML或注解方式配置.映射接口,以及实体类在数据库中的记 ...
- 02C++顺序结构(1)
1.C++程序的样子 2.流 输出流 COUT<< 3.一个实例及解析 4.小结 头文件的解释 头文件是C++程序对其他程序的引用,就是让编译器的预处理器把这个输入输出流的标准文件iost ...
- 部署docker-registry+ui shell 域名证书-用户认证
#部署docker-registry+ui shell docker registry 配置域名证书, 用户密码认证, 轻量UI ansible部署docker-registry+ui https:/ ...
- kafka各个版本的特性
1. kafka-0.8.2 新特性 1.1 异步发送 producer不再区分同步(sync)和异步方式(async),所有的请求以异步方式发送,这样提升了客户端效率.producer请求会返回一个 ...
- 在用Android StudioBuild项目时,提示:Could not resolve all files for configuration ':classpath'.Could not find com.android.tools.
在用Android StudioBuild项目时,提示:Could not resolve all files for configuration ':classpath'.Could not fin ...
- C#中Newtonsoft.Json(Json.NET)的使用
C#中Newtonsoft.Json(Json.NET)的使用. 添加引用: using Newtonsoft.Json; 调用代码: //获取图书列表 List<BookInfo> bo ...
- Python 抽象基类 ABC :从实践到优雅
今天我们来聊聊 Python 中的抽象基类(Abstract Base Class,简称 ABC).虽然这个概念在 Python 中已经存在很久了,但在日常开发中,很多人可能用得并不多,或者用得不够优 ...
- 【狂神说Java】Java零基础学习笔记-预科
[狂神说Java]Java零基础学习笔记-预科 预科01:学习准备:博客 博客,英文名为Blog,它的正式名称为网络日记 为什么要写博客? 需要总结和思考.有时候我们一直在赶路,却忘了放慢脚步 提升文 ...
- C Primer Plus 第6版 第三章 编程练习参考答案
编译环境VS Code+WSL GCC 源码在文末下载 /*第1题*************************/ #include<stdio.h> int main() { int ...
- Docker安装Redis并设置密码
1. 镜像下载 docker pull redis 2. 创建目录 mkdir -p /etc/redis/redis.conf mkdir -p /data/redis 3. 启动容器 docker ...