OI and C++
1.结构体重载运算符
语法还债系列1
(一般用于结构体的优先队列)举例说:
1 struct SP{int value,node;}; 2 bool operator <(SP a,SP b) 3 { 4 return a.value>b.value; 5 } 6 priority_queue<SP> hp;
改变小于号对于结构体SP的定义,让value小的结构体的被认为是“大”,value大的结构体的被认为是“小”,从而以结构体中的value为关键字建立一个结构体小根堆
2.下标为负的问题
c++数据下标为负时运行会爆出一个数,但是不会RE,在做递推/dp时可能会把它当成正常的答案,调试时要注意~~(欢迎使用pascal)~~
3.传值,传引用,传指针
语法还债系列2
写这条的起因是在写 p1005 矩阵取数游戏 时,因为std::string的高精常数太大,被卡t了一个点。最后在两次共产主义支援下,成功不开O2不稳定地过掉了(参见“奇怪汇总”)。然而自己初学时对语法和原理接触甚少,于是亲身实验+百度研究了一下函数的各种传参。
参考&感谢
@communist
现在有一个函数f,用来解决NOIP2017d1t1— —喜闻乐见的小凯的疑惑,它长这个样子
1 long long f(long long na,long long nb) 2 { 3 na-=1,nb-=1; 4 long long c=na*nb-1; 5 return c; 6 }
我们把它作为传值的例子,在主函数里这样写
1 balabalabala... 2 long long ans=f(a,b); 3 printf("%lld %lld %lld",ans,a,b);
输入3 7,输出11 3 7,原理大概是这样的:函数f从存储a的地址把a复制到na里,从存储a的地址把b复制到nb里,函数里关于na和nb的操作和a,b没有任何关系
接下来我们修改一下这个函数,改成传引用的形式
1 long long f(long long &na,long long &nb) 2 { 3 na-=1,nb-=1; 4 long long c=na*nb-1; 5 return c; 6 }
输入3 7,输出11 2 6。原理大概是这样的:函数f通过传引用找到na和nb的地址,然后直接修改这里存储的内容(a和b),所以最后输出时a和b都减去了1
我们再把函数f修改一番,改成传指针
1 long long f(long long *na,long long *nb) 2 { 3 *na-=1,*nb-=1; 4 long long c=*na * *nb-1; 5 return c; 6 } 7 ...... 8 balabalabala... 9 long long ans=f(&a,&b); 10 printf("%lld %lld %lld",ans,a,b);
输入3 7,输出11 2 6。原理大概是这样的:我们把a和b的地址作为参数传入函数f,函数把它们当做指针,根据na和nb两个指针找到指向的内存开始修改内存里的数(a和b)(然而我平时并不用指针)
然而关于传引用的问题,还没有完,我们如果这样写
1 long long f(long long &na,long long &nb) 2 { 3 na-=1,nb-=1; 4 long long c=na*nb-1; 5 return c; 6 } 7 balabalabala... 8 long long ans=f(a,7); 9 printf("%lld %lld %lld",ans,a,b);
就会喜闻乐见地CE掉。原因大概是这样的:我们直接把一个参数7塞进了函数里,而“7”这个常量没有所在的地址,函数也不可能“找到”,所以编译时会直接报错。如何解决呢?在传参数时用const修饰一下,就可以过了
1 long long f(const long long &na,const long long &nb) 2 { 3 na-=1,nb-=1; 4 long long c=na*nb-1; 5 return c; 6 } 7 balabalabala... 8 long long ans=f(a,7); 9 printf("%lld %lld %lld",ans,a,b);
对于类似于stirng的自带大常数的stl,在传参数时可以传引用以提高效率(注意如果会传常量要加const修饰,然后不能修改了),经实验(不管加不加const)应该对运行速度是有提升的
计划外的发现:只加上const修饰(传值),(至少对于string这类)速度应该也比直接传值快
然而我还有一个问题:为什么const修饰后就可以对常量传引用了呢,常量应该根本没法引用啊?哪位神犇看到了麻烦告知,谢谢quq。
ask ask ask
4.常数优化
通用(*是感觉作用不大/据说有用的):
register
能const的const掉,用多次的先求出来
快读快输(必要的时候贴一个fread)
尽量用临时变量,访问快
浮点数乘整型的时候把整型写在前面
实数二分考虑限制次数
三元运算符*
inline*
++i换i++*
struct/string这种“笨重”的东西考虑传地址
尽量避免数组多次寻址(指高维数组)
memset/memcpy的$\frac{1}{32}$常数*
cmath相关函数比较慢,考虑预处理
手写排序(快排/归并)
尽量减少递归
减法取模,注意只适用于当前答案超出模数不多的情况
有符号换成无符号
特殊:
矩阵乘法 i->k->j
char转int 直接xor 48
线段树记录左右端点*
沙雕:
循 环 展 开
松 松 松 排 序
指 令 集
---------------
睿智的蒟蒻yd提醒您:
卡常千万条,适度第一条
卡常不节制,亲人两行泪
6.常见各类型的变量的输入/输出及范围
语法还债系列3
int->%d----from $-2^{31}$ to $2^{31}$ $-1$ (<=$10^9$可用)(x10)
->%X(x16)
long long->%lld----from $-2^{63}$ to $2^{63}$ $-1$ (<=$10^{18}$可用)
unsigned long long->%ull----from $0$ to $2^{64}$ $-1$(<=$10^{19}$可用)
short->%hd----from $-2^{15}$ to $2^{15}$ $-1$(<=$10^4$可用)
double->%lf----整数部分+小数部分总计16位有效
long double->%Lf----经自己实验,纯整数/整数1位+小数总计18位有效;整数+小数似乎不稳定,但能保持在16位有效
7.DevC++的一些编译选项
①-Wall/-Wextra(显示最多警告/显示额外警告)
Tools->Compiler Options->Settings->Warnings->Show most warnings(-Wall)
②C++11
Tools->Compiler Options->Settings->Code Generation->Language standard(-std)->GNU C++11

浙公网安备 33010602011771号