第一周

来源:互联网 发布:阿里云服务器宽带 编辑:程序博客网 时间:2024/05/16 11:19

1.倍增LCA

求LCA有两种算法 一种是tarjan 另一种是倍增
tarjan学过但是忘记了(好菜)
倍增可以做到O(nlogn)预处理 O(1)的查询
运用倍增的思想
具体的做法是先对图进行一次dfs构造树 再倍增处理LCA
aij表示第i个点往上走2^j次的点

2.莫队算法

可以解决可离线查询的一类题目
具体利用分块的思想 把查询区间排序
然后利用一个update函数增长现有区间和delete函数缩短区间

一般形式是将查询区间记录并排序
有update函数和delete函数
初始化l=1,r=0(暂时还没见过其他形式的)

3.simson自适应积分
(还是借用大佬博客的图片)
这里写图片描述
积分的式子是这样的

不过在数字较大的情况下会产生误差
具体的处理方法是把积分区域分成两端
分别对 一整段积分 和 两段积分求和 比较差值
如果差值不大(即足够精确)就返回结果
如果差值过大就继续递归分别计算两段的积分并求和

4.hash

hash可以当作是对数据的一个映射
对于一个数据hash会处理出不同的特殊值
为了避免不同的数据处理出相同的特殊值 key一般都使用素数

一般的hash形式 : hash = (hash*seed+ai)%mod

5.最小表示法

可以求一串字符串中使串字典序最小的起始位置

int get(){    int i = 0, j = 1, k = 0;    while(i<m&&j<m)    {        k = 0 ;        while(b[i+k]==b[j+k]&&k<m)++k;        if(k==m)return i;        if(b[i+k]>b[j+k])        {            if(i+k+1>j)i = i+k+1;            else i = j+1;        }        else if(j+k+1>i)j = j+k+1;        else j = i+1;    }    return min(i,j);}

具体做法是先 让i=0,j=1
然后开始往后遍历
假设遇到 s[i+k]>s[j+k] 就 将i往后移
对小于的情况同理
这里用了 一个优化就是判断下一个点是否已经遍历过 有则跳过

6.神奇的STL

除了常用的set还有一个multiset即可重复集合
这个可以看作一个数组但是他内部是会自动处理成有序的
在维护某些东西例如线段长度的集合时可以减少冗杂的操作

7.树形dp

感觉就是DAG上的dp
dpij表示第i个点选j个的结果
递归处理下一个点后维护关于这个点的答案

8.欧拉回路

欧拉回路分为2种 并且需要满足不同的条件
无向图:连通(不考虑度为0的点),每个顶点度数为偶数
有向图:当成无向图的情况下 连通,同样不考虑度为0的点,每个顶点出度等于入度

一些图论题可能会涉及到欧拉回路
类似构造欧拉回路这种 需要观察结果拥有的性质

构造的方法是将边存起来 然后dfs遍历

9.扫描线+线段树

例题 stars in the window
用一个矩阵套尽量高分的星星
因为矩阵大小固定
考虑到在选中一个星星时尽量能套住更多的星星所以枚举矩阵时让这个星星在矩阵的左下角
星星可以被选的区域也是一个矩阵
把这些区域加上一个星星的权
那么区域中最大的某点的值就是解

用扫描线对二维空间降维
y轴进行扫描线 x轴利用线段树维护区间上的最大值
输入的时候在把范围控制在[x,x+w] 表示这区域加上星星的权 对y轴的坐标为y
再对同样的x轴上的区间 记录一个负权 y轴的坐标为y+h

往后遍历到i表示遍历到了yi然后更新区域内的权值
再直接取整棵树的最大值即为矩阵中可选的最大答案

10.离散

对于许多问题输入的数据会很大
类似ai<=1e9 这就不能直接用数组对ai记录 (类似cnt[ a[i] ])
这时候就用到离散

因为数据量一般都不会过大
所以用一个数组记下这些数
再用各个元素的序号来进行数据处理

int num[MAXN];vector<int>v;int getid(int x){    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}int main(){    scandd(n,m);    for(inti=1;i<=n;++i)scand(num[i]),v.push_back(num[i]);    sort(v.begin(),v.end());      v.erase( unique(v.begin(),v.end()), v.end() );}

11.矩阵快速幂

适用于常系数线性方程的快速求解

原理类似某个数的快速幂
对于矩阵乘法
aij = bik*ckj
主要是考虑如何构造递推式

构造出基础矩阵后对其自身进行一定次数幂次
再乘输入矩阵得到答案

12.分块算法

分块是把n长度分为sqrtn份的长为sqrtn的块
对于每段更新如果覆盖一整块则直接更新一整段块
如果覆盖一部分则暴力更新
复杂度为O(sqrtn)

例题:弹飞绵羊
对于每块的点记录他跳出这一块所需要的次数和下一个位置
从后往前更新

对一个点修改只会影响到这一块中他前面的点
因为如果前面的点是跳到修改的点 跳出块需要的次数会变化
而对前面一块某点跳出块的次数和位置没有影响

原创粉丝点击