杂项个人总结
留坑待填
多测不清空,爆零两行泪!
注意空间、注意CE
仔细读题,不要想当然!
仔细读题,不要想当然!!
仔细读题,不要想当然!!!
取模的题,输出时都加上%p+p%p
开变量时注意类型!!!区分intboolchar!!!
善于使用草稿纸,推式子,不要空想
int的inf和long long的一定要区别!!!好好想想inf的大小
注意看模数!!!
sort中,使比较函数 return 1的元素会往前;
priority_queue 默认大根堆;
数组开小了有时会MLE
读优会出现神奇的问题
迭代器的正确使用方法
vector<DataType>::iterator it =……;
vector使用技巧
vector<int>v;
v[1]=1;
此代码执行时会崩溃;因为初始时vector的size为0,无法储存任何值;
这时可以选择push_back()或resize(x);
如果不是强制在线,能不用priority_queue就用vector.sort,不然很慢;
注意memset的数组不要开太大;
printf的时候严格区分%d和%lld;
对于离散区间问题(比如数列问题),在拆分序列时注意边界问题,要+1/-1,不重不漏;
多组询问,一定要把每次的清零初始化做好!!!
如果枚举点对求贡献会T的话,不妨枚举每个边的贡献
注意DP时更新的顺序;
并查集可以在路径压缩的同时维护数据;
set维护的是最小值;
小数组不要在意大小,比如把字符映射到数组,数组起码开257;
向上取整
数组下标记得防越界,防负数;
正向进行操作很费劲?那就逆向试试
求XXX包含至少一个YYY的种类=XXX的种类-不含任何YYY的种类
注意int的inf和longlong的inf不一样,最好使用memset的无用位置
inf不要随便开,不要开太大,严格按照题目
右移时,如果超出int,务必1ll<<x
见到中位数,尝试二分答案
二分一个答案mid,将序列中所有小于mid的值赋值为-1,大于mid赋值为1,查询新序列有没有>=0的子段和,如果有,l=mid,else r=mid(+-1什么的具体分析);
不能用__int128
主席树的空间最好开200倍,越大越好
遇到各种弹出队列的情况,注意判空
能用数组不用结构体
给定一个序列,要求选出两个不相交的区间,使……
这样的问题往往可以转化为前缀后缀分别求一个区间,然后枚举中间点;
并查集处理区间问题
一定要
区间完全覆盖是
在更新一个点的值时,如果稍后还需要用到它的原始值,就要考虑修改的顺序
使用set.lower_bound时,注意!=set.end()
将询问换成前缀和相减时,记得扩大存放询问的数组;
遇到区间问题,前缀和无法解决,往往采取分块的办法,块的大小视区间大小来定(区间定长当然更好)
在统计时,如果采用相对值难以统计、修改、转移,不妨改成绝对值
set.insert也有返回值:
std::pair<iterator,bool> insert( value_type&& value );
bool表示是否插入成功;
不过最好别用;
求倒序和时,一定要倒序维护!!!
set是去重的
线型基在成功插入后要写break!!!
注意double的负零
比较两个长度为6的数组是否可以通过翻转,循环移动得到对方
bool cmp(int a[], int b[])
{
for(ri i = 0; i < 6; ++i)
for(ri j = 0; j < 6; ++j)
{
bool ok = 1;
for(ri k = 0; k < 6; ++k)
if(a[(i + k) % 6] != b[(j + k) % 6])
{
ok = 0;
break;
}
if(ok) return 1;
ok = 1;
for(ri k = 0; k < 6; ++k)
if(a[(i + k) % 6] != b[(j - k + 6) % 6])
{
ok = 0;
break;
}
if(ok) return 1;
}
return 0;
}
关于erase和iterator
1) 对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。
注意那个++,必须放在里面
set.erase(it++)
2)对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。还好erase方法可以返回下一个有效的iterator。
3)对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator,因此上面两种正确的方法都可以使用。
printf 输出 “%”
使用两个%
cout 设置位数
cout << fixed << setprecision(2) << double <<endl;
warn: fix
hihocoder 1383
字典树,注意区分文件夹名和文件名相同的情况;
区分set和multiset!!!
dfs全局变量存储容易冲突。
重载小于号不能重载小于等于号
本地用bitset最好用set、test,可以报告re
无理数的高精度处理:保留“a+b*根号”的形式:构造有序数对:(a,b),即可定义乘法。
Linux 下使用 -fsanitize=address 可以查RE(G++ 4.8+)
在对网格图编号后,通过编号还原位置,最好直接开个数组记
Trick
异或打标记实现(带随机性)的状态相同性确定。
Random_shuffle
windows下random_shuffle很弱,只会改变前32767个位置。可以手写一个random函数。
A=1<<15|3,B=33333331,C=(C*A+B),这组的循环节2e9左右。
做题一定要先挑可做的做...
在continue或break循环的时候,记得想想有没有什么要做的事没做
取模计数题不要出现负数!!!
取模真的很慢!!!避免大量的较小数乘法的取模!尝试都用LL存下来最后同一取模!
double的0/0是UB!
比赛时随时做记录:哪道题可做,那道题的哪个可写的部分分没写。
随机生成树高比较高的树
每次rand一条边
快速幂的b不要爆int!
发现自己调题调不出来,看看自己的每个数组,是不是忘了赋值