版权声明: https://blog.csdn.net/qq_40828060/article/details/80452108
目录
废话不多说,直接切入正题
读优
- .
-
这大概是我见过的码风最能接受的读优了…
总之好写好用,用就对了
inline int read(){
int re=0;
char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9'){
re=re*10+ch-'0';
ch=getchar();
}
return re;
}
输优
- .
-
这个输优不用开数组,而且好写,所以…
当然不需要换行就把\n给干掉…
inline void write(int x){
int y=10,len=1;
while(y<=x){
y*=10;
len++;
}
while(len--){
y/=10;
putchar(x/y+48);
x%=y;
}
putchar('\n');
}
求lg
- .
-
换底公式,在无理数后+1/+0.5来减少误差是个好习惯…
log2n=log(n)/log(2)+1
-
求n个数的lg
for(int i=1;i<=n;i++)
lg[i]=lg[i-1]+(1<<lg[i-1]==0);
树上的dfs(前向星存储)
- .
-
树上的dfs其实可以不用打访问标记,因为只需要不让连的点为父亲就好了
for(int i=head[u];i>-1;i=e[i].next)
if(e[i].v!=fa)
dfs(e[i].v,u);
流同步
- .
-
关闭:
ios::sync_with_stdio(false);
-
开启:
ios::sync_with_stdio(true);
精度误差
- .
-
产生原因是浮点数存储空间有限,导致无限循环数改变,这时一般需要+-esp(esp=1e-8)
至于为什么是1e-8,只能说是出题人默认 -
a>=0
–>a>-eps
a<=0
–>a<eps
-
还有个类似的操作
利用强制类型转换模拟四舍五入
doble a;
printf("%d",a+0.5);
位运算优化
- .
-
判断整数奇偶:
x&1
-
比较两数是否相等:
!x^y
-
判断两数是否同号:
!((x^y)>>31)
-
交换两个数:
a^=b;b^=a;a^=b;
-
求绝对值:
(n^(n>>31))-(n>>31)
双端队列
- .
- 简单来说就是左端是队列,右端是栈
Floyd求最小环
dis是被k更新过的,map是未更新的,二者刚好构成环
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(j=1;j<=n;j++)
ans=min(ans,map[i][k]+map[k][j]+dis[j][i];
Floyd求最短路的条数
用乘法原理更新最短路条数,分三种情况
1、当有新路径等于最短路,条数+=
2、当有新路径小于最短路,直接更新,条数=
3、新路径大于最短路,直接跳过
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
{
dis[i][j]=dis[i][k]+dis[k][j];
num[i][j]=num[i][k]*num[k][j];
}
if(dis[i][j]==dis[i][k]+dis[k][j])
num[i][j]+=num[i][k]*num[k][j];
}
伪去重离散化
//unique(u,v)返回去重(伪)后的地址,被删掉的会加到返回值后
//bo==lower_bound(u,v,x)返回最接近x的值的地址
int const maxn=1e5+10;
int a[maxn], t[maxn];
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",a[i]),t[i]=a[i];
sort(t+1,t+n+1);//排序,找相对大小
m=unique(t+1,t+1+n)-t-1;//m为不重复的元素的个数
for(int i=1; i<=n; i++)
a[i]=lower_bound(t+1,t+1+m,a[i])-t;//相对大小的
Cmp函数维护序列的稳定性
inline int cmp(int x,int y)
{
return a[x]>a[y];
}
inline int cmp(int x,int y)
{
return a[x]>=a[y];
}
上述两个cmp函数结果虽然相同
然而当遇到相同的数时
前者是按在原序列中出现的时间先后排序(时间先者先)
后者则是逆在原序列中出现的时间先后排序(时间后者先)