一些错误
一、比较致命的错误
都是可能会导致 \(100pts\to0pts\) 的错误。
1.状压或搜索中,如果当前数组只更新了 \([1,m]\) 的部分,而扫描它时用到了 \([1,n]\) 的部分,那么不要忘记将 \([m+1,n]\) 部分清空。
2.在函数中,一定要检查好某个变量是局部变量还是全局变量。防止某个全局变量被误认为是局部变量,而导致它的数值错误。
3.如果感觉空间不够,一定不要冒险将数组开得太大,因为一旦超空间可就一分没有。有一题,理论上暴力是20分,但空间只给了128MB,而20分的数据是1e8级别的。如果空间有所舍弃,开成1e7,能拿10分;而如果空间开1e8硬刚,能拿0分。
4.\(p[++tot].x=p[tot-1].x=k;\)是未定义行为,不能这么写。
5.开二维数组不要把大小开反。
6.仔细算清楚了到底需不需要开\(long\) \(long\)。例如统计逆序对时,\(10^5\)的序列的逆序对最多有约\(10^{10}\)个,需要开\(long\) \(long\)
7.取模不要把模数写错,尽量算一步模一次,不要爆int/long long
8.看清楚要输出什么。例如,看清 \(YES\) 和 \(YE5\) ,\(NO\) 和 \(N0\)。
9.读题分清楚子序列,子串,不要因为这个浪费时间。子序列不一定连续,而子串是连续的。
10.在写形如 \((a+b)\%p\) 的式子时,一定要注意 \(a\) 和 \(b\) 是不是负数,如果有负数一定要写成 \((a+b+p)\%p\) !
11.如果某个题写出了正解,一定不要懒,要自己造大数据验证一下!有的时候小数据说明不了任何问题!
12.\(STL\)的栈和队列容易爆空间。
13.不能使用的变量名或函数名:\(x1,y1,time,next,search,end,find,max,min\)
14.使用左移右移符号时,①如果运算结果不在 \(int\) 范围内,要写 \(1ll<<\) 或 \(1ll>>\) 的形式;②如果 \(n\) 特别大,就一定不要再写 \(1<<n\) 了,否则会爆掉。
15.在线性求积性函数时,一定要先求出函数值,再求前缀和。如果求函数值的同时求前缀和,会影响到后面的函数值!
16.在对序列求最大值的时候,如果序列中有负数,那么一定要把 \(maxn\) 赋值为 \(-INF\) .
17.在实数运算时,不要写 \(.../(i^2)\) 会被卡精度,要写成 \(.../i/i\) 。
二、关于特判
这部分如果没有考虑到,可能只会丢\(5-10pts\),但也不能不重视,也许就是这\(5-10pts\)使你与省队无缘。
1.自环和重边。
2.考虑只存在一个点,没有边的情况。这个比较重要,而且常被忽略。
3.图是否连通。
4.考虑模数为 \(1\) 的情况,以及一开始给定的数就大于模数的情况。
5.在写区间问题的时候,如果是自己造出了一个区间,一定要考虑是否存在区间为空,即 \(l>r\) 的情况。
三、具体的错误
一、线段树
1.支持区间加,区间推平的线段树的 \(push\_down\) (\(lazy1\)为下传值,\(lazy2\)为 \(0\) 表示区间加,为 \(1\) 表示区间推平):
void push_down(int u,int ul,int ur){
int mid=(ul+ur)>>1;
if(p[u].lazy2){
p[p[u].l].w=(mid-ul+1)*p[u].lazy1;
p[p[u].l].maxn=p[p[u].l].minn=p[u].lazy1;
p[p[u].r].w=(ur-mid)*p[u].lazy1;
p[p[u].r].maxn=p[p[u].r].minn=p[u].lazy1;
p[p[u].l].lazy1=p[p[u].r].lazy1=p[u].lazy1;
p[p[u].l].lazy2=p[p[u].r].lazy2=1;//这句话必须写在if里边,而不是外边!!!
}
else{
p[p[u].l].w+=(mid-ul+1)*p[u].lazy1;
p[p[u].l].maxn+=p[u].lazy1;p[p[u].l].minn+=p[u].lazy1;
p[p[u].r].w+=(ur-mid)*p[u].lazy1;
p[p[u].r].maxn+=p[u].lazy1;p[p[u].r].minn+=p[u].lazy1;
p[p[u].l].lazy1+=p[u].lazy1;p[p[u].r].lazy1+=p[u].lazy1;
}
p[u].lazy1=p[u].lazy2=0;
}
注释的那句话不能在 \(if\) 外边写成 \(p[p[u].l].lazy2=p[p[u].r].lazy2=p[u].lazy2;\) ,因为如果当前 \(p[u]\) 只下传区间加,不下传区间推平时,它的左右儿子是否下传区间推平不能受它本身的影响。
二、AC自动机
在 \(ask\) 函数中:
//if(p[k].end)这个if一定要去掉!!!
while(t){
++ans[p[t].end];
t=p[t].fail;
}
因为每扫到一个节点就要遍历所有的 \(fail\) ,即使当前这个节点不是结束点。
三、分块
1.特判 \(l\) 和 \(r\) 在同一块内的情况。
2.在写区间查询有多少个数大于某个特定值时,不要忘记将初始的数排序。

浙公网安备 33010602011771号