挖坑:数据结构的题

BZOJ

树上的维护:

3282: Tree

连边、删边;单点点权修改;查询路径点权XOR和。
裸LCT。

1984: 月下“毛景树”

单边边权修改;路径边权覆盖/加某常数;查询路径边权MAX。
双标记(note:覆盖和加的双标记可以转化为乘和加的双标记,即乘0或1后再加某值)。裸LCT/树链剖分。

3306: 树

换根;单点点权修改;查询子树点权MIN。
线段树维护DFS序。
至于换根操作,不用真的换。设原先的根为1,现在的根为rt,要求询问子树u。讨论三种情况(1)rt==u(2)u是rt的(真)祖先(3)其他,看“子树u”到底是哪一部分。其中要用到倍增。

3083: 遥远的国度

换根;路径点权覆盖;查询子树点权MIN。
树链剖分、DFS序。
对某个点DFS的时候优先沿其重边往下走,这样得到的DFS序中,每条重链都是连续一段出现的,从而可以支持链修改。
换根的处理方法同3306。

3123: [Sdoi2013]森林

初始时为一棵森林,需要支持连边;查询路径点权第K小。(强制在线)
启发式合并、主席树。
先离散化。给每棵树定一个根开始DFS。DFS时建好根到每个结点的权值线段树(权值事先离散化),同时处理出倍增数组用于求LCA。
连边(u,v)时,Tu和Tv被合并,不妨设size(Tu)>=size(Tv),那么把v接到u下面成为其孩子,然后往下对Tv进行DFS,重构权值线段树以及倍增数组。复杂度是O(logn*size(Tv))的。
最后总复杂度是O(nlog^2n)。简证:考虑任意某个元素,其对复杂度作出贡献时一定属于两树中较小的一棵,合并后它所在的树大小至少是两倍,于是不超过logn次。

1146: [CTSC2008]网络管理Network

单点点权修改;查询路径点权第k小。
法①:
DFS括号序、树状数组套主席树。
DFS括号序中,左括号为插入(次数+1),右括号为删除(次数-1)。从而根到每个结点的路径可以转化为一个前缀和。u到v的路径可以表示成T(u)+T(v)-2*T(x)+x,其中x=lca(u,v)。于是可以用主席树。为支持修改需用树状数组套。
查询O(log^2n),修改O(log^2n),空间O(nlog^2n)。
法②:
DFS括号序、线段树套平衡树。
最外层对权值建一棵线段树,每个线段树结点对应一棵储存下标的平衡树。把left[u]、right[u]插到包含w[u]的线段树结点所对应的那些平衡树中去。平衡树结点需维护size域,并且把right[u]结点的size标为-1。
查询时只要在最外层线段树二分。
(线段树用树状数组代替也可)
查询O(log^2n),修改O(log^2n),空间O(nlogn)。

3153: Sone1

3052: [wc2013]糖果公园

1758: [Wc2010]重建计划

3319: 黑白树

3307: 雨天的尾巴

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成所有发放后,每个点存放最多的是哪种物品。
树链剖分。
先考虑是一条链上的情况,把所有发放的左端点记为+1(表示放入),右端点记为-1(表示取出),放到一起排序。然后从左到右扫描,扫的同时用一个堆/线段树来维护目前的物品集合,遇到+1或-1就相应地更新集合。扫完就能得到所有答案。
剖完以后,每次发放就被拆成了logn次在重链内的发放。每条重链分别统计答案即可。

序列上的维护:

2038: [2009国家集训队]小Z的袜子(hose)

莫队。把序列均匀分为m段。对询问排序时优先按左端点所在段的编号升序,若左端点处于同一段内的,再按右端点升序排。这样左端点移动了O((n/m)*q),右端点移动了O(m*n)。
m取O(sqrt(n))。

3289: Mato的文件管理

询问区间逆序对数量。
莫队。
树状数组维护当前区间内所有权值及出现次数,同时维护逆序对数量。

1756: Vijos1083 小白逛公园

单点修改;查询区间最大连续子段和。
线段树。
每个结点维护4个域,权值和、左端点为起始的最大子段和、右端点为结束的最大子段和、不加限制的最大子段和。于是线段树里可以方便地合并两个儿子节点。

1500: [NOI2005]维修数列

splay/块状链表的自虐题。

2741: 【FOTILE模拟赛】L

询问区间内最大连续子段xor和。(强制在线)
分块、函数式trie。
求前缀和,转化成求两个元素xor和的最大值。
每个数看成二进制01串。从1到n依次插入建成函数式trie。时间O(nlogA)。
序列均匀分成m段。预处理:通过m次扫描整个序列,对每一对1<=i<=j<=m,求出第i段到第j段内的答案ans[i][j]。时间O(nmlogA)。
询问:找出包含在l,r内的完整的段i,i+1,……,j,若所求区间端点在这些段内,答案即是ans[i][j]。若区间某个端点(或两个都)在这些段以外,暴力枚举。完整段外的零头是O(n/m)级别,所以复杂度O((n/m)*logA)。
取m=O(sqrt(n))。
(加一减一之类的细节要当心)

3188: [Coci 2011]Upit

区间权值覆盖;插入单个元素;区间加等差数列;询问区间和。
Splay。
覆盖和插入不用多说,关键在于等差数列的处理。结点的标记a,d表示对该区间加了等差数列a,a+d,…,a+(size-1)d。标记容易合并:a+a’,a+d+a’+d’,…,a+(size-1)*d+a’+(size-1)*d’相当于a+a’,(a+a’)+(d+d’),…,a+a’+(size-1)(d+d’)。
标记也容易下传,一个等差数列断成的两截仍是等差数列。

3339: Rmq Problem

询问区间内权值的mex。
离线。
从1到n枚举区间右端点i,同时维护一棵权值线段树。线段树的叶子节点x储存1<=j<=i且a[j]==x的最大j(x未出现过就记j=0),线段树内部结点储存它下面的叶子的值的min。扫到i时更新线段树里a[i]处的值。然后回答以i为右端点的询问,用左端点去比较并沿着线段树根下降到叶子即为答案。

2821: 作诗(Poetize)

查询区间内出现次数为正偶数的权值有几种。(强制在线)
分块。
法①:
将序列均匀分成m段,预处理a[i][j]表示前i段中,权值j的出现次数。O(nm)。
预处理b[i][j]表示第i段到第j段(i<=j)内的答案。
查询时,找出包含在l,r内的完整的段i,i+1,…j,于是我们有第i到j段的答案b[i][j]以及其中任意权值x的出现次数a[j][x]-a[i-1][x]。再把段外的零头的权值插入(cnt++),插入时维护答案的变化。每次查询复杂度O(n/m)。(记得查询完后把插入的值删掉)
取m=sqrt(n),于是总时间O((n+q)sqrt(n)),空间O(nsqrt(n))。(空间不是很靠谱)
法②:
O(nm)预处理b[i][j]表示第i段到第j段(i<=j)内的答案。
对每个权值x建一个序列,按升序储存所有满足a[i]=x的下标i。
查询时,找出包含在l,r内的完整的段i,i+1,…j,于是我们有第i到j段的答案b[i][j]。把段外零头出现过的权值挑出来,对于其中某一种权值,可以在其下表序列中二分,求得它在区间l,r内出现的次数,再讨论其奇偶性对答案的影响,更新答案。每次查询的时间是O(n/m * logn)。
取m=O(sqrt(n)),总时间大概是O((n+q)sqrt(n)log(n))的样子,空间是O(n)的。

2874: 训练士兵

3065: 带插入区间K小值

3064: Tyvj 1518 CPU监控

2738: 矩阵乘法(梁 盾)

维护一个矩阵,每次询问某个子矩阵的第K小数。矩阵边长500,询问次数6万。
整体二分。
把所有格子按权值升序排。离散化权值后,设当前二分的权值范围是[l,r],此范围内的询问集合是Q。
若l==r,那么Q内所有询问的答案就是l对应的权值。
否则,
1)给权值在[l,mid]范围内的格子加一(用二维树状数组维护)。
2)对Q内的每个询问,用二维树状数组统计后看各自的K值是否达到,并依此将Q分成Q1,Q2。
3)递归处理[mid+1,r],询问集合为Q2。
4)给权值在[l,mid]范围内的格子减一
5)递归处理[l,mid],询问集合为Q1。
若边长为A,权值总数为O(A^2)。排序复杂度为O(A^2logA^2)=O(A^2logA)。
每个询问出现在O(logA^2)=O(logA)层,每次查询O(log^2A),所以步骤2)的复杂度总共O(Qlog^3A)。
剩下的复杂度T(n)=2T(n/2)+O(n*log^2A)=O(nlognlog^2A)。
所以总复杂度O(A^2logA)+O(Qlog^3A)+O(A^2*logA^2*log^2A)=O((A^2+Q)log^3A)。

1176: [Balkan2007]Mokia

维护一个矩阵(初始为空)。修改某格权值;查询某个子矩阵的权值和。矩阵边长200万,修改次数16万,询问次数1万。
CDQ分治。
所有修改和询问按时间顺序组成一个操作序列T。处理T[1..n]即可。
处理T[l..r]时:
1)递归处理左半部分T[l..mid]。
2)统计T[l..mid]中修改对T[mid+1..r]中询问的贡献。
不妨设所有询问矩阵的x1都是1(否则写成两个这样的矩阵的差)。将左半部分的修改和右半部分的询问放在一起,按照x(修改操作按照x2)升序排序,若x相同则修改在前询问在后。然后x从1开始扫,扫的同时维护y轴上的一棵树状数组,并相应进行修改/查询,并把求得的贡献值累加到该询问的答案上。
3)递归处理右半部分T[mid+1..r]。
设矩阵边长为A,T(n)=2T(n/2)+O(nlogn)+O(nlogA)=2T(n/2)+O(nlogA)=O(nlognlogA),离散化后即是O(nlog^2n)。

2683: 简单题

同1176。

3262: 陌上花开

给定n个三元组(a,b,c),对每个三元组统计满足a’<=a,b’<=b,c’<=c的(a’,b’,c’)的数量。
CDQ分治。
关 键在于等号的处理。按a排序,并把a值相同的三元组放到一个段内。CDQ分治时以段为最小单位,这样每次将序列分成两部分时,可以保证左半部分的a都严格 小于右半部分的a,于是我们可以统计a’

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值