Re:memset 赋值

前言

赋值其实用 for 也是可以的,但是 memset 更快。有人又说 fill 不错,但是 fill 的常数几乎是 memset 的二倍,而且代码长度也比 memset 长 (其实这个才是主要原因,for 太长了)

各种类型的 sizeof 的大小

1
2
3
4
5
6
7
8
9
10
11
12
13
sizeof(short)=2
sizeof(int)=4
sizeof(long long)=8
sizeof(__int128)=16
sizeof(unsigned short)=2
sizeof(unsigned int)=4
sizeof(unsigned long long)=8
sizeof(__uint128_t)=16
sizeof(float)=4
sizeof(double)=8
sizeof(long double)=16
sizeof(char)=1
sizeof(bool)=1

其实不需要记这么多,sizeof(type) 就是每个这种变量类型的字节大小,表示数的时候 1B1\operatorname{B}88 位,例如 int 范围为 231+12311-2^{31}+1\sim 2^{31}-1,加上符号位一共有 3232 为,所以 sizeof(int)44;而像 charbool 都只需要单一字节,所以他们的 sizeof 为 11

memset 赋值原理

memset 是按字节赋值的,意思就是说把这个数的每一个字节都设置为这个数。例如 memset(f,1,sizeof f),那么假设这个数组是 int 型的,则其中每个元素都是 (00000001000000010000000100000001)2=(16843009)10(00000001000000010000000100000001)_2=(16843009)_{10}。所以说如果你不直接用 sizeof arr,那么前面还要加上 sizeof(type) 这个系数,因为其实这个值代表的是从起始开始赋值多少个字节。

memset 赋极值

对于整型变量

memset(f,-63/63,sizeof f) 无疑是最佳选择,因为 127127 是去掉符号位时的最大值,但是如果就赋 127/127-127/127,那么它的两倍就爆炸了,实用性不高;而赋为 63/63-63/63,它的两倍就不会爆炸。

对于浮点类型

memset(f,0X43,sizeof f) 为保证 double 进度下的最大值。

memset(f,0Xc0,sizeof f) 为保证 double 精度下的最小值。

注意事项

  • memset 赋值是从下标 00 开始的,如果要让他从第 ii 个开始赋值应将第一个参数改为 f+i
  • 最好算字节数,慎用 sizeof f,使用这个多组数据极其容易 TLE;但如果是多维数组,可以使用,但是依旧有可能 TLE,建议使用 for。
  • memset(f,a,sizeof f) 只有在 a=1/0a=-1/0 时恰好赋值 aa;其他值,例如 11,只能使用 for 或 fill。
  • 如果数组变量类型为 char 赋值直接是对应字符的 ASCII 码值;如果是 bool,那么赋为直接 00 或者 11 即可。

最后

如果用 memset 怎么样都调不出来,就改成 for 吧。。。