然而好像没有平衡树

还是题解包:

T1:森林

树上主席树+启发式合并。

然而好像知道标签就没啥了。在启发式合并时可以顺手求lca

然而这题好像可以时间换空间(回收空间)

T2:影魔

难点在于考虑贡献的来源

考虑一个区间两端点和区间最值(不含端点)的关系

小,中,大:贡献p1

大,小,大:贡献p2

大,中,小:贡献p1

则预处理出每个点左右第一个比它大的数的位置,设为l和r

则l会对r有p2的贡献,l会对i+1~r-1产生p1的贡献,同理r会对l+1~i-1产生p1的贡献。

用线段树维护扫描线,正向,逆向分别扫一遍,先把贡献都加进线段树,扫到某个点时先统计贡献再在线段树中减掉贡献。

具体实现见代码


T3:世博会

其实难点在于将切比雪夫距离转化为曼哈顿距离,然后主席树维护即可,将两维分开考虑,分别取中位数即可。

T4:Obserbing the tree树上询问

可持久化线段树+标记永久化。在线段树的每个节点维护等差数列的首项和公比,利用标记永久化减少节点数量

新建一个状态类似于主席树的建树,用树剖维护即可(线段树也是按dfs序建的)

 #include<bits/stdc++.h>
#define N 200050
#define LL long long
#define int long long
using namespace std; int he[N],ne[N<<],to[N<<],cnt;
inline void addedge(int x,int y){
to[++cnt]=y;ne[cnt]=he[x];he[x]=cnt;
} int n,m;
int rt[N];
int lc[N*],rc[N*],tot;
LL sum[N*],d[N*],s[N*];
inline LL cal(int a,int d,LL n){
return a*n+d*(n-)*n/;
}
inline void upd(int g,int n){
sum[g]=sum[lc[g]]+sum[rc[g]]+cal(s[g],d[g],n);
}
int merge(int x,int y,int l,int r){
if(!x||!y)return x|y;
s[x]+=s[y];d[x]+=d[y];
if(l^r){
const int m=l+r>>;
lc[x]=merge(lc[x],lc[y],l,m);
rc[x]=merge(rc[x],rc[y],m+,r);
}
sum[x]=sum[x]+sum[y];//////
return x;
}
void bl(int g,int l,int r)
{
if(!g)return;
//printf("g:%d l:%d r:%d s:%d d:%d sum:%d\n",g,l,r,s[g],d[g],sum[g]);
const int m=l+r>>;
bl(lc[g],l,m);bl(rc[g],m+,r);
}
void add(int &g,int l,int r,int x,int y,LL a,LL b)
{
if(l>y||r<x)return;
if(!g)g=++tot;
if(l>=x&&r<=y){
s[g]+=a+b*(l-x);
d[g]+=b;
upd(g,r-l+);
return;
}
const int m=l+r>>;
add(lc[g],l,m,x,y,a,b);
add(rc[g],m+,r,x,y,a,b);
upd(g,r-l+);
}
LL ask(int g,int l,int r,int x,int y)
{
if(!g||l>y||r<x)return ;
if(l>=x&&r<=y)return sum[g];
const int m=l+r>>;
int tl=max(l,x),tr=min(r,y);
LL ret=cal(s[g]+d[g]*(tl-l),d[g],tr-tl+);
return ret+ask(lc[g],l,m,x,y)+ask(rc[g],m+,r,x,y);
} int dl[N],dr[N],dep[N],tp[N],hs[N],pos[N],f[N],sz[N];
inline void dfs1(int g,int fa){
dep[g]=dep[fa]+;sz[g]=;f[g]=fa;
for(int i=he[g];i;i=ne[i]){
if(to[i]^fa){
dfs1(to[i],g);
if(sz[to[i]]>sz[hs[g]])hs[g]=to[i];
sz[g]+=sz[to[i]];
}
}
}
inline void dfs2(int g,int fa){
dl[g]=dr[g]=++cnt;pos[cnt]=g;
tp[g]=g==hs[fa]?tp[fa]:g;
if(hs[g])dfs2(hs[g],g);
for(int i=he[g];i;i=ne[i])
if(!dl[to[i]])dfs2(to[i],g);
}
inline int LCA(int x,int y){
while(tp[x]!=tp[y]){
if(dep[tp[x]]>dep[tp[y]])swap(x,y);
y=f[tp[y]];
}
if(dep[x]<dep[y])return x;return y;
} inline void work(int &g,int fr,int to,LL a,LL b)
{
if(dep[fr]<dep[to])return;
while(tp[fr]!=tp[to]){
add(g,,n,dl[tp[fr]],dl[fr],a+b*(dl[fr]-dl[tp[fr]]),-b);
a+=b*(dl[fr]-dl[tp[fr]]+);
fr=f[tp[fr]];
}
add(g,,n,dl[to],dl[fr],a+b*(dl[fr]-dl[to]),-b);
}
inline LL getans(int g,int fr,int to)
{
LL ret=;
while(tp[fr]!=tp[to]){
ret+=ask(g,,n,dl[tp[fr]],dl[fr]);
fr=f[tp[fr]];
}
ret+=ask(g,,n,dl[to],dl[fr]);
return ret;
}
main()
{ scanf("%lld%lld",&n,&m);
for(int i=,x,y;i<n;++i){
scanf("%lld%lld",&x,&y);
addedge(x,y);addedge(y,x);
}
cnt=;dfs1(,);dfs2(,);
char s[];int x,y,a,b;LL lasans=,ts=,now=;
while(m--)
{
scanf("%s",s);
if(s[]=='c'){
scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
x^=lasans;y^=lasans;
++ts;
int lca=LCA(x,y),dis=dep[x]+dep[y]-dep[lca]-dep[lca];
// printf("%d %d %d\n",x,y,lca);
work(rt[ts],x,lca,a,b);
work(rt[ts],y,lca,a+b*dis,-b);
add(rt[ts],,n,dl[lca],dl[lca],-(a+(dep[x]-dep[lca])*b),);
rt[ts]=merge(rt[ts],rt[now],,n);
// bl(rt[ts],1,n);
now=ts;
}
else if(s[]=='q'){
scanf("%lld%lld",&x,&y);
x^=lasans;y^=lasans;
int lca=LCA(x,y);
lasans=getans(rt[now],x,lca)+getans(rt[now],y,lca)-getans(rt[now],lca,lca);
printf("%lld\n",lasans);
}
else{
scanf("%lld",&now);
now^=lasans;
}
}
return ;
}

T5:Alo

此题考察可持久化trie+RMQ

因为要取区间次大值,所以要找出以每个数作次大值的区间即可,

对于每个数,先找到右面第一个比它大的,然后再向右找到第二个比它大的,这个过程可以用二分+rmq实现,这样就得到了它作为次大值的右端点,reverse一下就得到了左端点,用trie在区间找到最值即可

T5:最大异或和

可持久化trie的板子题

可持久化数据结构(平衡树、trie树、线段树) 总结的更多相关文章

  1. 浅谈可持久化Trie与线段树的原理以及实现(带图)

    浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...

  2. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  3. POJ2104 K-th Number 不带修改的主席树 线段树

    http://poj.org/problem?id=2104 给定一个序列,求区间第k小 通过构建可持久化的点,得到线段树左儿子和右儿子的前缀和(前缀是这个序列从左到右意义上的),然后是一个二分的ge ...

  4. BZOJ_3196_二逼平衡树_(树套树,线段树+Treap)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3196 可以处理区间问题的平衡树. 3196: Tyvj 1730 二逼平衡树 Time Lim ...

  5. cogs 1829. [Tyvj 1728]普通平衡树 权值线段树

    1829. [Tyvj 1728]普通平衡树 ★★★   输入文件:phs.in   输出文件:phs.out   简单对比时间限制:1 s   内存限制:1000 MB [题目描述] 您需要写一种数 ...

  6. COJ 1010 WZJ的数据结构(十) 线段树区间操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: ...

  7. 1588. [HNOI2002]营业额统计【平衡树-splay 或 线段树】

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

  8. 洛谷 P3285 / loj 2212 [SCOI2014] 方伯伯的 OJ 题解【平衡树】【线段树】

    平衡树分裂钛好玩辣! 题目描述 方伯伯正在做他的 OJ.现在他在处理 OJ 上的用户排名问题. OJ 上注册了 \(n\) 个用户,编号为 \(1\sim n\),一开始他们按照编号排名.方伯伯会按照 ...

  9. [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]

    题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...

随机推荐

  1. git版本控制系统重新认识

    git 版本控制系统 目标:完全搞懂git分布式版本控制系统 搭建git版本控制系统 cvs集中化版本控制系统--集中式管理的服务器 git分布式版本控制系统--会将原始代码仓库镜像下来 新项目使用g ...

  2. Linux入职基础-1.2_U盘安装RedHat5具体步骤

    从U盘安装RedHat5具体步骤 从U盘安装RedHat Linux的具体步骤: 准备工作: RHEL_5.6_i386_DVD.ISO文件 具体步骤: 1.解压并用ultraiso软件打开rhel- ...

  3. vs项目模板创建和使用

    一.使用dotnet命令创建(适用于.NET Core,可以创建包含任意数量个项目的模板,但不会出现在vs的新建项目模板中) 官方文档:https://docs.microsoft.com/zh-cn ...

  4. 单例模式详解以及需要注意的地方(Singleton)

    单例模式,顾名思义,就是在Java程序中只有唯一一个实例,这样做的好处是可以在不需要多个实例的对象采用单例模式可以节省内存,否则会造成不必要的内存浪费.单例模式的定义为:保证一个类只有一个实例,自己可 ...

  5. 基于【 springBoot+jsoup】一 || 爬取全国行政区划数据

    一.代码演示 如果中途中断,可进行刷选过滤已拉取省份数据 /** * TODO * * @author kevin * @createTime 2019-11-18 19:37 */ @RestCon ...

  6. 微信小程序错误readFile:fail parameter error: parameter.filePath should be String instead of Undefined;

    我是在使用camera组件时遇到的该问题 原因是未保存文件路径(微信使用摄像头拍照后会把图片保存在一个临时的路径,所以你需要自己定义一个变量来存这个路径,以备下次使用该变量去访问文件) 所以加上你需要 ...

  7. vue简单todolist

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Linux Centos7 网络设置UUID号的修改方法

    1.生成一个UUID [root@localhost ~]# uuidgen ens33 223bdb47-2fed-4773-b984-5f5733e61904 2.UUID号写入网络配置文件ifc ...

  9. javascript_10-函数

    函数 //定义函数 0-100 相加 function getSum() { var sum = 0; for (let i = 1; i <= 100; i++) { sum += i; } ...

  10. c# 属性成员