基础算法模板(自用篇)
二分
while(l<=r){
int mid=l+r>>1;
if(check(mid,a)) {
ans=mid;
r=mid-1;//根据具体情况修改 可能这里是l=mid+1
}else {
l=mid+1;
}
}
并查集
朴素版
//并查集也可以用来统计连通块的数量,从而进行一些操作
//https://ac.nowcoder.com/acm/contest/95937/D
const int N=1e5;
int p[N];//存父节点
int sz[N];//统计以该点为祖先的结点数量(包括祖先自己)
int find(int x)
{
return x==p[x]? x:p[x]=find(p[x]);
}
void merge(int x,int y)
{
x=find(x),y=find(y);
if(x!=y)
{
p[x]=y;//把x的父节点设置为y
sz[y]+=sz[x];//相应的结点数量加上去
}
//涉及到以最小编号为祖先可以这么写
//if(x<y) sz[y]=x;
//else sz[x]=y
}
//注意区分 find(x) 与p[x] 的区别
//find(x) 是直接找到该点的祖先 p[x]只是找到其父节点
快速幂
using i64=long long
#define mod 998244353;
i64 qpow(i64 a, i64 n) //快速幂 a为底数 n为次方
{//经常配合逆元来使用。 1/x=qpow(x,mod-2);
//当遇到除法精度不够可以选择用乘法逆元来代替解决
i64 res=1;
while(n){
if(n&1) res=res*a%mod;
a=a*a%mod;
n>>=1;
}
return res%mod;
}
组合数
int C(int a,int b)// a为分子部分 b为分母部分
{
//组合数的分子上下部分可以用递推推出来
//分母用逆元来处理
//这样就可以降低时间的复杂度
return a*qpow(b,mod-2)%mod;
}
找连通块(非自环)的数量
int GetCircle()
{
int res=0; //环的个数
for(int i=1;i<=n;i++)//遍历存了下一个位置的数组元素
{
if(!vis[i]){//未标记过就去找环
int id=i;
while(!vis[id]){
vis[id]=1;//走过就标记
id=ve[id];//把当前位置改为下一个位置
}
res++;
}
}
return res;//返回答案
}
posted on 2025-04-06 14:44 swj2529411658 阅读(26) 评论(0) 收藏 举报
浙公网安备 33010602011771号