题记: 由于编程中出现问题太多, 本人总是得过且过, 故记此贴, 供以后自己参阅, 内容可能过于杂乱, 故不喜此贴者, 关闭网页. 此文后续会频繁更新
记录点滴细节
1. 1<<17+1 ⇔ 1<<18 解释: 由于' +' 的优先级为2>优先级为5的' <<'.
同理 i>>j&1 ⇔ (i>>j)&1 解释: 位运算&的优先级较低
2. it = set.erase(it) 结果: 此时it指向之前的后面的结点.
3. greater 在set中的作用使其从大到小排列
4. map<char, int> mp 如果有后续语句 cout<<mp['f']<<endl; 那么map会自动新生成f对象
5. 对于必要的++, --不要轻易放进if语句中
6. Teemo的莫队dfs序中,先出现的点L一定比较小, 如果某点是另一点的ancestor, 则L[u]<L[v]&&R[v]==R[u], 该情况下只需要对L[u]和L[v]之间的树段进行处理,
另一种情况下从R[u]到L[v]之间的树段进行查找. 莫队排序对R出现的末点进行排序, 那么此题可以分治(算法以后完成).
7. 递归算法优点: 形式简洁, 可读性好, 正确性容易得到证明. 可以给程序的编制和调试带来很大的方便.
递归算法的缺点: 递归调用比非递归调用时间空间复杂度高, 运行效率较低.
8. 矩阵快速幂中row表示当前状态, line表示转移状态.
9. rak[i] = j 代表i位置的大小序为j, pos[i] = j 代表第i小的数的位置为j. // 两者都可以通过对pair进行一次排序来完成
10.关于平衡二叉树(AVL树) 的旋转
左左丶右右只需进行一次旋转, 左右, 右左需进行两次旋转. 以左左丶左右为例附图如下:
11. 树的存储结构3种:
1.child表示法: 每个结点记录记录child
2.child&brother表示法: 每个结点记录最左的child和自己右边brother
3. father表示法: 每个结点*pre指向father(此方法可以用来表示等价类(t(A)=A&&r(A)=A&&s(A)=A) )
12. A 树转化成二叉树, 链接兄弟结点, 取出除根与长子结点之外的其他边
B 森林转化成二叉树 先用A的方法转化所有树, 然后依次往别的右结点加
C 某点连所有左子结点的右节点 擦除所有点的右连线
13. 多次使用 ios::sync_with_stdio(0)会出现wrong answer的情况
14.手动扩栈
#include <sys/resource.h>
bool increase_stack_size( int size_mb ) {
struct rlimit rl;
if ( getrlimit(RLIMIT_STACK,&rl)!=0 ) return 0;
rl.rlim_cur=size_mb*(1<<20);
if ( rl.rlim_cur>rl.rlim_max ) rl.rlim_cur=rl.rlim_max;
return setrlimit(RLIMIT_STACK,&rl)==0;
}
15.分块是一个有效降低时间复杂度的方法, 类似的:
for (int i = 1, last = 0; i <= l; i = last + 1)
{
last = min(l / (l / i), r / (r / i)); //找到和下面函数值相同的最大量
ans += (ll)(l / i) * (r / i) * (sum[last][p] - sum[i - 1][p]);
}
16.前缀积不能维护0