一些错误

一、比较致命的错误

都是可能会导致 \(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.在写区间查询有多少个数大于某个特定值时,不要忘记将初始的数排序。

posted @ 2023-07-23 14:44  andy_lz  阅读(54)  评论(0)    收藏  举报