首页 > 其他分享 >2024 省选复习 (updating)

2024 省选复习 (updating)

时间:2024-02-27 10:15:05浏览次数:24  
标签:二分 端点 树状 省选 sum 2024 数组 莫队 updating

前言

快省选了,在复习,但是不知道干什么。

所以就写点东西吧。

就是瞎写写,所以可能有很多错误,如果发现了欢迎指出。


常见错误 & 注意事项

  1. 数组不能开大,也不能开小

  2. 题目要求什么千万不能读错,最好手算一下样例


算法复习

树状数组进阶

P6619

原本是树状数组二分的模板题,但是用树状数组 + 二分水过去了。

其实就是要求冰火两方消耗能量较少的 2 倍,所以要让这个最小值最大。

发现其实冰系战士消耗的能量关于温度是一个上升的斜线(本质上是一个前缀和),火系下降(本质上是一个后缀和)。

所以它们的最小值最大应该是在交点处。但线不连续,所以要找两个位置,一个是最后一个 \(sf_i\geq sc_i\) 的位置,一个是第一个 \(sc_i>sf_i\) 的位置,很显然的二分。带修所以树状数组维护前缀和。

这样二分是在整个树状数组上的,根据树状数组的结构可以用类似倍增的方式 \(O(\log n)\) 过去。而不需要 \(O(\log ^2 n)\) 的树状数组 + 二分

树状数组二分可以抽象成这样一类问题:存在分割点 \(q\),使得 \(\leq q\) 的位置满足某个限制,而 \(> q\) 的位置不满足该限制,求 \(q\)。

从大到小考虑 \(1\leq 2^k \leq n\),每次尝试将 \(p\) 加上 \(2^k\),由于从大到小枚举,根据树状数组的结构,\(c_{p+2^k}\) 存的值即为 \(\sum_{i=p+1}^{p+2^k} a_i\),所以直接加上这个值判断一下,若满足就 \(p\leftarrow p+2^k,s\leftarrow s+c_{p+2^k}\),否则不动,然后继续枚举。其实就是一个倍增。

但是树状数组二分只适用于在整个树状数组上二分,如果是局部,就没办法利用树状数组的结构了。所以还是需要树状数组 + 二分


P4602

整体二分 + 树状数组二分


P3586

似乎并不需要树状数组二分。

这题主要难在结论的推导,推出性质之后似乎就是一个简单的离线维护了。


P4514

二维树状数组的模板。

二维树状数组维护二维前缀和。

设 \((i,j)\) 差分数组为 \(d_{i,j}\),\(s_{i,j}\) 表示 \((i,j)\) 的二维前缀和

\[s_{x,y}=\sum_{i=1}^x \sum_{j=1}^y a_{i,j} \]

\[=\sum_{i=1}^x \sum_{j=1}^y \sum_{k=1}^i \sum_{l=1}^j d_{k,l} \]

\[=\sum_{i=1}^x \sum_{j=1}^y d_{i,j} \cdot (x-i+1)\cdot(y-j+1) \]

\[=\sum_{i=1}^x \sum_{j=1}^y d_{i,j} (xy-xj+x-yi+ij-i+y-j+1) \]

\[=\sum_{i=1}^x \sum_{j=1}^y d_{i,j} [(xy+x+y+1)-i(y+1)-j(x+1)+ij] \]

所以维护 \(d_{i,j},d_{i,j} \cdot i,d_{i,j} \cdot j,d_{i,j}\cdot ij\) 四个二维树状数组就可以了。。

放一个二维树状数组的代码

struct BIT{
    int s[maxn][maxn];
    void add(int x,int y,int z){
        for(int i=x;i<=n;i+=lowbit(i))
            for(int j=y;j<=m;j+=lowbit(j)) s[i][j]+=z;
        return ;
    }
    int ask(int x,int y){
        int res=0;
        for(int i=x;i;i-=lowbit(i))
            for(int j=y;j;j-=lowbit(j)) res+=s[i][j];
        return res;
    }
};

根号分治

就是利用根号平衡的思想,对于不同的数据用不同的维护方法。本质是数据分治

CF797E

CF1039D

CF1580C


莫队

CF617E & P4462

莫队板题。首先把区间异或和转为两个异或前缀和的异或,然后维护一个区间内异或前缀和值 为 \(i\) 的数个数。


P4396

莫队 + 值域分块

发现对于一些没法 \(O(1)\) 插入删除的东西,如果使用 \(\log\) 数据结构,整体复杂度就变为了 \(O(n\sqrt n \log n)\),无法接受。

但是其实对于所有询问,修改操作有 \(n \sqrt n\) 次,但是询问操作只有 \(n\) 次,所以我们考虑继续运用根号平衡的思想,找一些 \(O(1)\) 修改,\(O(\sqrt n)\) 查询的方式,即值域分块。

但是有的时候我们有不同的需求,比如有时候二次离线需要 \(O(\sqrt n)\) 修改,\(O(1)\) 查询,此时换一种值域分块的方式,见 P5501 的二离部分,要注意区分。


P4887

有的时候我们没有办法 \(O(1)\) 实现插入删除,也没法值域分块(比如每次插入删除会考虑一个点对一个区间的贡献),所以我们需要把这些点对区间的贡献的询问离线下来再做,即莫队二次离线。

每一次端点移动可以看为一堆点对于一些区间的贡献,一般来说这种东西具有可减性。

记 \(f(i,[l,r])\) 表示点 \(i\) 对 \([l,r]\) 的贡献,假设某次移动右端点由 \(r\) 移动到 \(r'\),贡献为

\[\sum_{i=r+1}^{r'} f(i,[l,i-1])=f(i,[1,i-1])-f(i,[1,l-1]) \]

前半部分东西可以扫一遍预处理,对于后半部分,看成一段区间对一段前缀的贡献。
考虑将 \(g([r+1,r'],[1,l-1])\) 挂到 \(l-1\) 上,然后再从前往后扫加入每个点,然后暴力回答挂在这个点上的询问,由于莫队端点移动的总长度是 \(O(n\sqrt n)\) 所以可以接受。

P5501 中二次离线部分依然不能 \(O(1)\) 处理,此时发现添加点(即修改操作)是 \(n\) 次,查询是 \(O(n\sqrt n)\) 次,此时我们需要修改根号,查询 \(O(1)\) 的数据结构。

注意:

  1. 贡献的符号

  2. 有时候要注意贡献的含义,比如逆序对,是查区间内比某个数大还是比某个数小。


P5906

有的时候我们维护的信息不支持删除,比如最大值最小值,这个时候需要一种不用删除的莫队,即回滚莫队。

回滚莫队的思想是,把左端点在一个块内的询问按右端点从左到右排序(所以不能奇偶排序优化了,悲),每次把左端点放在块尾,然后向右移动右端点,遇到询问就暴力左移左端点,询问完后再撤回,把左端点放回块尾。

看上去很暴力,但是复杂度是对的。


P7708

较为复杂的莫队。


fhq-treap

标签:二分,端点,树状,省选,sum,2024,数组,莫队,updating
From: https://www.cnblogs.com/wonderfish/p/18036270

相关文章

  • 20240226
    非常意识流的日记,精神状态极度不佳下打出来的。模拟赛垫底,不过是意料之中的,没造成太大影响。下午也很正常,一直在硬刚Border,不过有些微疲倦。晚自习就开始颓废了,不想学习。然后下去散步的时候唐了,成小丑了,破防了。当时看到青蛙的博客时真正体会到了什么是「整个人都麻了」的......
  • 2024.2.26
    前言还有\(4\)天就结束了呜呜呜,我还不想走,我还没打过国赛呜呜呜。博弈以为是个吊题,结果真是签到题啊QAQ。首先我们要读明白题,我们一个点可以放多个棋子,所以可以得出一个结论:每个点是互不影响的。所以我们可以每个点分开来算。正如题解所说:“因为在自己所属点上的棋子是完......
  • 近期总结 2024.2.26
    dp专场*2。CF1608FMEXCounting题意:给出\(n,m,b_{1...n}\),求出有多少个长度为\(n\)的序列\(a\)满足\(\foralli\in[1,n],\space0\lea_i\len\)且\(|\operatorname{mex}\{a_1,a_2,...,a_i\}-b_i|\lem\)。\(1\len\le2000,\space1\lek\le50\)很简单的......
  • NOI 2024省选OIFC模拟21 蒲巴巴 超繁做法
    题目描述一年一度的PuBaBa杯开始了!今年的PuBaBa杯总共有\(n\)个选手来参加,编号分别为\(1,2,\cdots,n\),他们的水平按编号依次递增,所以他们过的题目数量单调不降。作为本场比赛的出题人,PuBaBa总共出了\(m\)道题,他希望第\(i\)道题至少有\(l_i\)个选手通过,至多有\(......
  • 2024.2.25模拟赛T3题解
    题目推出dp柿子之后,枚举\(i\)的时候用线段树维护\(1-i\)的\(mex\)段,对于每一段,分别使用线段树套李超树维护,对于每个\(mex\)再次使用线段树套李超树维护即可code#include<bits/stdc++.h>usingnamespacestd;#defineN600005#defineintlonglongintn,m;consti......
  • .NET周刊【2月第3期 2024-02-25】
    国内文章4.1kStar!全面的C#/.NET/.NETCore学习、工作、面试指南https://www.cnblogs.com/Can-daydayup/p/18027117DotNetGuide是一个为.NET开发者建立的技术社区和知识库。其中包含.NET相关的学习资料、工作心得、面试指南、技术文章、项目框架和常见面试题等,目的是帮助初学者......
  • 2024牛客寒假算法基础集训营4
    2024牛客寒假算法基础集训营4A 柠檬可乐题意根据给定的\(a\)和\(b\),判断是否\(a\gek\timesb\)思路题意非常直接代码/*******************************|Author:AlwaysBeShine|Problem:柠檬可乐|Contest:NowCoder|URL:https://ac.nowcoder.com/acm/......
  • 2024.2.25模拟赛T1题解
    题目考虑DP式子之后,可以通过堆维护函数,求出对应值code#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineN200005intzu,n,d,tg,num;inta[N];priority_queue<int>q;signedmain(){ scanf("%lld",&zu); while(zu--){ scanf(&qu......
  • 2024.2.25模拟赛T2题解
    题目枚举根之后,考虑每次连边的贡献,通过贡献算出每个点的权值,每次找出权值最大的点,又要保证父亲在儿子之前,所以将父亲和儿子合并,权值也合并一下即可code#include<bits/stdc++.h>usingnamespacestd;#defineN2005intans,n,k;intsz[N],deg[N],du[N],fu[N],f[N],h[N];str......
  • 2024.2.26模拟赛T2题解
    题目对询问扫描线,建出\(PAM\)的失配树之后,每次查询相当于,把\(r\)对应节点到根路径染色之后,有多少个节点的值大于\(l\),可以树剖+ODT实现code#pragmaGCCoptimize("Ofast","inline","-ffast-math")#pragmaGCCtarget("avx,sse2,sse3,sse4,mmx")#include<bits/s......