qwq

可优化dp:转移、状态都是一维的

优化思路:单调栈、单调队列、数据结构、斜率优化

T1:
无限制:C(x+y-1,x)
不可行:C(x+y-1,x-1)

目标,顺序,剪枝

树状数组:
O(logn):单点修改、求前缀和、区间修改、区间求和

堆:
快速插入删除、查询最大最小

并查集:
代表元、优化:路径压缩+按秩合并O(n*alpha(n))+启发式合并O(nlogn)+随机合并

SET:
有序集合(序列)+快速插入删除+区间求第k大

MAP:O(log)
开大数组
unordered_map:O(1)–>c++ 11

dfs序:
子树对应区间

区间减法:差分前缀和

bitset

区间修改->单点修改:差分

cdq分治:
前提条件:修改操作互不影响
etc:区间取最值:有影响 区间求和:相互独立

点事件+扫描线

Day 3题解:
按位%|^:每一位相互独立

一、存图:
1、邻接矩阵:O(1)查询、O(n^2)遍历
2、边表

二、最短路
1、Floyd 多源最短路O(n^3)
2、dijkstra O(n^2+m)
3、STL堆优化dij O((n+m)logm)
4、手写堆优化dij O((n+m)logn)
5、斐波那契堆优化dij O(n
logn)
6、spfa 最坏O(n
m)

三、生成树
最小生成树:
{
prim O((n+m)logm)
kruskal O(m
logm) <–优先!
}
<注>考虑非树边替换树边
矩阵树定理Matrix Tree Theory:对于有n个点的完全图,有n^(n-2)棵生成树
非严格次小生成树:有且仅有一条边与最小生成树不同
{
求最小生成树,枚举删边,重新跑最小生成树:O(n*m)–>60分
枚举加一条边,删去环上最长边即求树链最长边 -->100分
}
【例题】货车运输+四川省选day1 t1
【例题】CF160D edge in mst
我们定义一条非树边所构成环上的所有树边被这条非树边覆盖
枚举每条非树边,与被其覆盖的最小边比较
如果相等,则两者都可能在,如果不等,则非树边一定不在,树边一定在
【例题】bzoj 2234
【例题】bzoj 2654
wqs+最小生成树
性质1:白边边权越大,在最小生成树中的白边越少
性质2:黑边与白边相对独立且白边关系不变
【例题】bzoj 3332 旧试题
四、强连通分量
有向图:强连通分量
无向图:点双连通分量(割点:删去一个点使图不连通)、边双(桥)
tarjan缩点–>DAG消灭环+topsort使得所有点有序(前指向后)+从左到右有序的dp

五、匹配
二分图匹配:(匹配:左与右连边)(在每一个点只匹配一个点的前提下求最多匹配)
{
匈牙利算法 复杂度上界:(邻接矩阵:O(n^3) 边表:O(n*m))
dinic
}
二分图模型:树(奇数深度连向偶数深度)、网格图(每个图连向周围四个点)
网络流:【例题】网络流24题+2009年胡伯涛论文<最小割模型在信息学竞赛中的应用>
费用流

六、最大团(最多的点两两有边)=补图的最大独立集(两两无边)
最小割最大流定理:最大独立集=左点+右点-最大团
{
一般图:NPC问题(n<=20)
特殊图(非NPC):二分图
}
【例题】P2423朋友圈(好题)

Day 4 动态规划
用别人更新自己
for(int i=1;i<=n;i++)
f[i]=f[i-1]+a[i];
f[i][j]表示在i-j的最小次数

区间DP
状态:f[l][r]表示l-r的答案
转移:O(n)枚举l-n的松弛点,将l-r劈成两半,然后对两个小区间合并
<注>枚举区间长度!从小区间到长区间转移

树形DP
状态:f[i]存以i为根的子树的信息
转移:将子树的信息合并O(n)
f[i]=inf[i]+sigma(son[j])f[j];
<注>从深度深向浅转移

数位DP
从高位向低位填数
状态:f[i][j][k] 从高到低第i位,j.k为0/1变量,表示是否>=l.<=r
转移:枚举下一位填什么数()
状态:f[i][j] j表示<=某个数x
然后用前缀和统计答案
【例题】P2657 windy数

状压DP
用1个数表示某些数选了或没选的状态
状态:O(2^n)(n<=23)
<没法转移加一维>
<多一个限制加一维>
转移:
for(int i=0;i if(!(s>>i)&1)
f[(s|(1< TSP问题
O(n2*2n)
基于连通性的状态压缩动态规划

插头DP
HDU Eat the tree

排列DP
排列问题一般需要排序
因为DP需要满足一定顺序
向一个排列中加一个数
【例题】codechef FEB14 LEmovie

【例题】数字三角形2
【例题】P3541
【例题】bzoj 2757
【例题】阿狸与桃子的游戏
【例题】bzoj

Day 5
Oeis做法:
a[n]=(n-1)(2(n3-2*n2+n+1)a[n-1]/(n-2)+((n^2-2n+2)(n+1)a[n-2] +(2n2-6*n+1)*n*a[n-3]+(n-3)*(a[n-4]*(n3-5n^2+3)-(n-4)(n-1)(n+1)a[n-5])))/(2n))
第n项的答案位数小于10n,高精度把n项的答案算出来,这个值对p取模。

正解:
得一行一行放
dp[i][][][][] 前i行棋子的状态是? ? ? ?,此时的方案总数
黑棋是每行每列放两个,白棋是每行每列放一个
一行一行枚举时,强制让每行放2黑的,1白的,只要考虑所有列符合条件就可以了。
一个列: 白 放 / 没放 黑 放1个/没放/放两个
dp[i][a][b][c][d][e][f] 表示前i行,0白0黑的列有a列,0白1黑的有b列,0白2黑的有c列,1白0黑…
a+b+c (0个白的列的个数) +d+e+f(放了1个白的列的个数) = n
对于第i+1行,枚举3个棋子放的状态,O(1)转移
O(n^7) -> O(n^6)
对于白棋,因为每行放一个,现在总共放了i行,所以肯定有i列放了白棋。
d+e+f=i。
O(n^6) -> O(n^5)
对于黑棋,每行放两个,所以有
b+e+2c+2f = 2*i
O(n^5) -> O(n^4) n=50

f[i][a][b][d] -> c,e,f是多少
枚举第i行怎么放的时候, 这3个棋子每个棋子都有6种可能, 6^3。
没有白棋,只有黑棋。 O(n)的做法 f[n]=(n-1)(f[n-1]+f[n-2])
n=2 f[2]=1 f[3]=6 f[4]=21.
f[n]表示一个n
n的矩阵, 方案总数是多少。
f[n-1] f[n-2] -> f[n]
f[n]=C(n,2)*((n-1)f[n-2]+2f[n-1])

g[i][j] 表示 [i,j]取一段子区间,没有元素重复,使得子区间长度最长 n^2
g[i][j-1] g[i+1][j] [i,j]没有元素重复
for (i=n; i>=1; i–)
{
for (j=1; j<=n; j++) v[j]=false; FLAG=true;
for (j=i; j<=n; j++)
{
if (v[a[j]]) FLAG=false;
v[a[j]]=true;
if (FLAG) g[i][j]=j-i+1; else g[i][j]=max(g[i+1][j],g[i][j-1]);
}
}

先把所有符合条件的区间全部搞出来,由这些区间取扩展到g更大
[A,B]是合法的, 则 g[A][B]=B-A+1 g[l][r] l<=A r>=B 都有g[l][r]>=B-A+1 n^2

先枚举第一段区间的右端点r,当l=1时,求出所有×的位置,并求出第二段区间能取的最大长度。
随着l往右走,部分×被解锁,更新第二段区间的最大长度(并查集实现),然后更新答案。

f[i]表示在并查集树上的父亲,i的祖先就表示从i出发向右最近×的位置。

x这个位置被解锁了,getf(x+1)表示新增的区间右端点在哪里, 更新f呢,f[x]=getf(x+1);


Day 6
看到奇偶数个1,想到^和等于1 or 0

Day 7
vector 查询、插入 O(n) 动态增减内存 O(size)
使用stl一定要注意数组越界和访问非法内存!
dequeue可实现单调队列
map 插入映射 O(logn) (n<=10w)
映射int:无限大数组
映射string 哈希!
map的迭代器按横坐标排序 O(nlogn)
set *a.end()返回末尾地址+1,需要 *–end()
集合从小到大排序 O(nlogn)
插入集合 O(logn) (n<=40w)
可利用指针找第k小 …++(++a.begin())
堆:O(log(n))插入、取最小
nth_element:O(n) 找序列第k小
reverse:区间翻转
random_shuffle:将数组随机洗牌
next_permutation:O(n)
binanry_search
swap交换两个数组的充要条件:数组长度相同

整理技巧


二维树状数组、二维前缀和
树上差分
ST表
矩阵乘法:具有结合律+左右分配律、不具有交换律
逆序对
分数规划
master定理

你可能感兴趣的:(noip)