2024.11.24 鲜花

一些大概有用的东西

hello (bpm)2024

翻洛谷科技·工程翻到的,大概有点用。

大量参考洛谷日报。

  1. 负数下标数组

    int _f[N],*const f=_f+(N>>1); 不解释。

  2. valarray

    挺强的,但常数也不小。

    定义类似 vector,但是是固定长,可以用 .resize(n,t=T()) 重设大小,但是会清空。

    类似 bitset,重载了运算符,如 a+=b 表示 a 的每一位都加上 b(的每一位),其中 b 可以是数,也可以是 valarray

    也重载了一些单变量函数如 sqrt(),若是自己的函数是模板函数可以直接用,否则可以用 a.apply(x),其中 x 是作用到每一位的函数。

    有一些如有用的函数:.sum() .max() .min() 就是字面意思。

    .shift(x) 向左位移,x 为负就是向右,空位补 \(0\),需要注意的是这个不会对其做修改,而是返回一个修改后的,修改要写成 a=a.shift(x)

    .cshift(x) 是循环位移,其他和 .shift(x) 一样。

    有非常牛的 mask_array

    不好解释,给两个例子,还是能感受到那股劲的:

    a[a%3==0]+=5 表示将 a 中所有值是 \(3\) 的倍数加 \(5\)

    valarray<int> b=a[a%3==0] 其中 ba 中所有值是 \(3\) 的倍数的值组成的子集。

    这里面可以传任意 \(bool\) 类型的表达式。

    还有切片:a[slice(x,y,z)] 其中 slice 是一个内置函数,传的 x,y,z 分别是起始位置、步长和切片长度。

    还有一点要注意的是它会实时更改,也就是说 v[j][k]-=v[f[i]][k]/v[f[i]][i]*v[j][i]; 大概不是你想要的值。

    好像是会建表达式树,有的编译器还会并行优化,反正好像要比手写封装快一点。

  3. 位域

    就是你卡空间是有时会有取值在 \([0,3],[0,10^5]\) 这种有点卡边的变量。如果多的话可以扔到位域里。

    位域只能定在结构体里,定义类似。

    struct T{
        int a:4;
        unsigned b=2;
    };
    

    冒号前面是类型和变量名,后面是大小,单位是 \(bit\)。注意大小不要超过类型大小。

    可以用 int :0 这种来舍掉当前字节后缀。

    结构体大小大概是每个大小的和向上取整到最大类型字节。

    位域不能开数组,但是其结构体可以。

    类型的作用是限制其运算,比如说 int 越界会成负,unsigned 不会但是也不能存负。

    本质上是时间换空间,带挺大常数,大概本地不开越界检测对 \(10^8\) 赋值一次加访问一次要 \(0.3s+\)

Nine Gates(第九道门)

posted @ 2024-11-24 20:39  xrlong  阅读(51)  评论(4编辑  收藏  举报