个人感觉各方面难度高于《在美妙的数学王国中畅游》,也不知道是不是求导的关系,这题 \(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] 决战 题解的更多相关文章

  1. BZOJ3159: 决战

    方法很简单,树剖,把区间提取出来,打翻转标记,再放回去. 注意:由于某种原因,我写的是把题目中的r忽略掉的一般情况,否则简单得多. 本来以为写起来也很简单T_T #include<bits/st ...

  2. BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)

    题目描述 输入 第一行有三个整数N.M和R,分别表示树的节点数.指令和询问总数,以及X国的据点. 接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路. 接下来M行,每行描述一个指令或 ...

  3. bzoj3159决战 码农题 树剖套splay

    最近沉迷码农题无法自拔 首先有一个暴力的想法:对于每个重链维护一个splay,需要翻转的连起来,翻转,接回去 然后发现这样没问题... 一条链只能跨log个重链,也就只有log个splay的子树参与重 ...

  4. BZOJ3159: 决战(FHQ Treap)

    传送门: 解题思路: 算是补坑了,这题除了Invert以外就可以树剖线段树解决了. 考虑Invert操作,延续先前树链剖分的做法,考虑先前算法的瓶颈. 最暴力的方法是暴力交换权值,然而这种方法忽略了当 ...

  5. 2017-12 CDQZ集训(已完结)

    从联赛活了下来(虽然分数倒一……),接下来要去CDQZ集训啦…… DAY -2 2017-12-16 被老师安排负责一部分同学的住宿以及安排…… 抓紧时间继续学习,LCT真好玩啊真好玩…… 晚上放假了 ...

  6. CDQZ集训DAY2 日记

    依然很爆炸. T1上来有50分暴力分,打完后注意到了后50分的随机数据,开始想怎么去对付他.然后就开始思考随机数据意味着什么.想了想,想打一个扫描线或者分治.决策了一下还是打了一个扫描线+链表.然而只 ...

  7. 2013 CSU校队选拔赛(1) 部分题解

    A: Decimal Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 99   Solved: 10 [ Submit][ Status][ Web ...

  8. ypACM社团年终赛暨实验室选拔赛题解

    记得补题,题目两小时半还是挺困难ak的,毕竟我验题也验了几天的时间,题目基本没有锅.题目基本属于简单题 我的三道题都是很基本的题目,希望大家补题 这些题解都是我写的,如果有疑问可以qq问我 所有的核心 ...

  9. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  10. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

随机推荐

  1. 使用redis 的订阅服务

    1.业务使用场景 我们在使用表单动态添加字段,如果新增字段,再保存数据,这个时候就会出错,出错的原因是seata 再本地缓存元数据,修改物理表的时候,这个元数据并没有发生变化,因此需要刷新元数据,因为 ...

  2. HTML5 多媒体

    1.互联网上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比如 Flash)来播放的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了在网页上嵌入音 ...

  3. C/C++源码扫描系列- codeql 篇

    首发于 https://xz.aliyun.com/t/9275 概述 codeql 是一个静态源码扫描工具,支持 c, python, java 等语言,用户可以使用 ql 语言编写自定义规则识别软 ...

  4. cas3.5配置LDAP域控

    一. 安装cas3.5 点击下载 CAS 3.5.2 :CAS 解压缩下载的 cas-server-3.5.2-release.zip,在 %CAS%\modules文件夹中找到cas-server- ...

  5. 【杂谈】服务端能同时处理多少个 Socket 连接?背后的资源与限制分析

    一个服务端进程能同时连接多少个 Socket? 要理解一个服务端进程能同时支持多少个连接,首先我们需要明确一个 socket 连接 的表示方式.一个连接由四个部分组成:[LocalIP:LocalPo ...

  6. Microsoft Build 2022 专家对话

    Microsoft Build 2022 专家对话 Build 2022 专家对话地址:https://mybuild.microsoft.com/en-US/sessions/81056450-6f ...

  7. 使用PG的部分索引

    PG 又带来一个惊喜. 现在有一张表,每天增加几十万数据,数据量迅速超过 1亿.此时 create_at 上的索引已经非常庞大,检索速度很慢. 接下来要分表分区了? NO,PG 有一个非常有意思的特性 ...

  8. TS 原理详细解读(6)--语法增量解析

    呃....4年前开了一个坑,准备写一套完整介绍TS 原理的文章.坑很大,要慢慢填,今天就来填一个把. 本节主要介绍语法增量解析. 什么是增量解析 增量解析的意思是,如果我们直接从源码解析成语法树,叫做 ...

  9. postgres

    10.67 su - app  docker pull postgres:12.15  docker run -d --name pgsql12 -p 5432:5432 -e "POSTG ...

  10. Qt编写视频监控系统71-外网访问摄像头等设备(获取各种信息及拉流)

    一.前言 最近遇到个需求是通过外网接入摄像机或者NVR,通用的做法是将视频流推流到服务器,然后拉取rtmp视频流,这样就多了服务器的要求,而且实现的功能有限比如不能直接用onvif协议对设备获取信息和 ...