然而好像没有平衡树

还是题解包:

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. Linux文件属性整理

    Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限.为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定.在Linux中我们可以 ...

  2. 上传图片,图片过大压缩处理以及解决自拍时会出现图片横屏的bug修复、长按保存图片

    js部分:module.exports = { resize: function (file, callback, options) { //配置 options = Object.assign({ ...

  3. Ipython 和 python 的区别

    IPython是一个python交互shell,它比默认的python shell更易于使用.它支持自动变量完成.自动缩进.bash shell命令,并且内置了许多有用的函数和函数. IPython是 ...

  4. weblogic jdbc 相关概念介绍

    weblogic jdbc 是什么? 如何配置? 常见问题? 如何监控?

  5. Android NDK 学习之Android.mk

    Android.mk file syntax specification Introduction: This document describes the syntax of Android.mk  ...

  6. C++ 虚表虚函数怎么就实现了多态?

    虚表vftable,编译器为每个拥有虚函数的类都建有一张虚函数表,里面存有虚函数的入口指针(地址).在类对象的内存布局中,先是一个vfptr虚表指针,指向虚表首地址,而后通过偏移量的形式来访问虚表中的 ...

  7. pyhton中map和reduce

    from functools import reduce import numpy as np ''' reduce[function, sequence[, initial]]使用 1.functi ...

  8. cmd中for的用法

    在cmd窗口输入for /?后的原文,被我自己“翻译”了一下,更像人话了. 推荐去https://www.cnblogs.com/cbugs/p/8992059.html这篇部落格里去看看,讲的更好. ...

  9. python之tkinter入坑Pack()------(1)

    tkinter 的pack()可以设置的属性如下: pack_configure(self, cnf={}, **kw)Pack a widget in the parent widget. Use  ...

  10. XSS挑战之旅平台通关练习

    1.第一关 比较简单,测试语句: <svg/onload=alert(1)> <script>confirm(1)</script> <script>p ...