基础算法模板(Acwing)

1.快速排序(Acwing 785.快速排序

void quick_sort(int a[],int l,int r)
{
  if(l>=r)return;
  int i=l-1,j=r+1,x=l+r>>1;//'+'的优先级高于'>>'移位运算符
  while(i<j)
  {
    do i++;while(a[i]<x);
    do j--;while(a[j]>x);
    if(i<j) swap(a[i],a[j]);
  }
  quick_sort(q,l,j);
  quick_sort(q,j+1,r);
}

解析:
1.首先设立一个X将数组分开成两个数组;
2.设立两个指针i和j分别从首尾两端向彼此靠近,将小于X的数据都放在X的左边,大于X的数据放在X的右边。当两个指针相遇时,继续下一步;
3.将左边的数据和右边的数据继续进行上面的操作;
4.重复上述过程,可以看出这是一个递归的过程;当左右两边的数据都排好序之后,整个数组就自然有序了。

2.归并排序 Acwing 787.归并排序

void merge_sort(int a[],int l,int r)
{
  if(l>=r)return;
  int mid=l+r>>1;
  merge_sort(a,l,mid);
  merge_sort(a,mid+1,r);
  int k=0,i=l,j=mid+1;
  while(i<=mid&&j<=r)
  {
    if(q[i]<q[j])tmp[k++]=q[i++];
    else 
      tmp[k++]=q[j--];
  }
  while(i<=mid)tmp[k++]=q[i++];
  while(j<=r)tmp[k++]=q[j--];
  for(int i=l,k=0;i<=r;i++)
    q[k++]=tmp[i++];
}

3.整数二分算法模板 Acwing 789.数的范围

bool check(int x)
{
  /* ... */
}//检查x是否满足某种性质
//区间[l,r]被划分成[l,mid]和[mid+1,r]时使用
int bsearsh_1(int l,int r)
{
  while(l<r){
    int mid=l+r>>1;
    if(check(mid))r=mid;
    else l=mid+1;
  }
  return l;
}
//区间[l,r]被划分成[l,mid-1]和[mid,r]时使用
int bsearsh_2(int l,int r)
{
  while(l<r){
    int mid=l+r+1>>1;
    if(check(mid))l=mid;
    r=mid-1;
  }
  return l;
}

4.浮点数二分模板 Acwing 790.数的三次方根

bool check(int x)
{
  /*  */
}//检查x是否服从某种性质
double bsearsh(double l,double r)
{
  const double e=1e-6;
  while(l<r)
  {
    double mid=(l+r)/2;
    if(check(mid)) r=mid;
    else l=mid;
  }
  return l;
}

5.高精度加法 Awcing 791.高精度加法

//C=A+B,A>=0,B>=0
vector<int>add(vector<int> &A,vector<int> &B)
{
  if(A.size()<B.size()) return add(B,A);
  int t=0;
  vector<int> C;
  for(int i=0;i<A.size();i++)
  {
    t+=A[i];
    if(i<B.size())t+=B[i];
    C.push_back(t%10);
    t/=10;
  }
  if(t)C.push_back(t);
  return C;
}  

6.高精度减法 Acwing 792.高精度减法

//C=A-B,A>=B,A>=0,B>=0
vector<int>sub(vector<int> &A,vector<int> &B)
{
  if(A.size()<B.size()) return sub(B,A);
  vector<int> C;
  for(int i=0,t=0;i<A.size();i++)
  {
    t=A[i]-t;
    if(i<B.size())t-=B[i];
    C.push_back(t+10%10);
    if(t<0) t=1;
    else t=0;
  }
  while(C.size()>1&&C.back()==0)C.pop_back();//去除前导0
  return C;
}  

7.高精度乘低精度 Acwing 793.高精度乘法

//C=A*b,A>0,b>0
vector<int>mul(vector<int> &A,int b)
{
  vector<int> C;
  int t=0;
  for(int i=0;i<A.size()||t;i++)
  {
    if(i<A.size())t+=b*A[i];
    C.push_back(t%10);
    t/=10;
  }
  return C;
}  

8.高精度除以低精度 Acwing 794.高精度除法

//C=A*b,A>0,b>0
vector<int>div(vector<int> &A,int b)
{
  vector<int> C;
  int r=0;
  for(int i=A.size()-1;i>=0;i--)
  {
    r=r*10+A[i];
    C.push_back(r/b);
    r%=b;
  }
  reverse(C.begin(),C.end());
  while(C.size()>1&&C.back()==0)C.pop_back();
  return C;
}  

9.一维前缀和 Acwing 795.前缀和

S[i]=a[1]+a[2]+...a[i]
a[l]+...+a[r]=S[r]-S[l-1]

10.二维前缀和 Acwing 796.子矩阵之和

S[i,j]=第i行j列格子左上部分所有元素的和
以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵之和为:
S[x2,y2]-S[x1-1,y1-1]+S[x2,y1-1]+S[x1-1,y1-1]

11.一维差分 Acwing 797.差分

给区间[l,r]中的每个数加上c:B[l]+=c,B[r+1]-=c

12.二维差分 Acwing 798.差分矩阵

给定(x1,y1)为左上角,(x2,y2)为右下角的子矩阵中的所有元素加上c:
S[x1,y1]+=c,S[x2+1,y1]-=c,S[x1,y2+1]-=c,S[x2+1,y2+1]+=c

13.位运算 Acwing 801.二进制中1的个数

求n的第k为数字:n>>k&1
返回n的最后一位1lowbit(n)=n&-n

14.双指针算法 Acwing 799.最长连续不重复子序列Acwing 800.数组元素的目标和

for(int i=0,j=0;i<n;i++)
{
  while(j<i&&check(i,j)) j++;
  //具体问题的逻辑
}
常见分类问题:
    (1)对于一个序列,用两个指针维护一段区间
    (2)对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

15.离散化 Acwing 802.区间和

vector<int> alls;//存储所有待离散化的值
sort(alls.begin(),alls.end());//将所有值排序
alls.erase(unique(alls.begin(),alls.end()));//去掉重复元素

//二分求出x对应离散化的值
int find(int x)//找到第一个大于等于x位置
{
  int l=0,r=all.size()-1;
  while(l<r)
  {
    int mid=l+r>>1;
    if(alls[mid]>=x)r=mid;
    else  l=mid+1;
  }
  return r+1;//映射到1,2,...n
}

16.区间合并 Acwing 803.区间合并

//将所有存在交集的区间合并
typedef pair<int, int> PII;
void merge(vector<PII> &segs)
{
  vector<PII> res;
  sort(segs.begin(),segs.end());
  int st=-2e9,ed=-2e9;
  for(auto seg:segs)
    if(ed<seg.first)
  {
    if(st!=-2e9)  res.push_back({st,ed});
    st=seg.first,seg.second;
  }
  else
    ed=max(ed,seg.second);
  if(st!=-2e9)res.push_back({st,ed});
  segs=res;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高精度算法是指能够处理超出计算机基本数据类型范围的数字运算问题的算法。常见的高精度算法有大整数加减乘除、高精度开方、高精度取模等。 以下是acwing的高精度算法模板: 1. 大整数加法 C++ 代码: vector<int> add(vector<int> &A, vector<int> &B) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || i < B.size(); i++) { if (i < A.size()) t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t) C.push_back(1); return C; } 2. 大整数减法 C++ 代码: bool cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] > B[i]; } return true; } vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 3. 大整数乘法 C++ 代码: vector<int> mul(vector<int> &A, int b) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || t; i++) { if (i < A.size()) t += A[i] * b; C.push_back(t % 10); t /= 10; } return C; } vector<int> mul(vector<int> &A, vector<int> &B) { vector<int> C(A.size() + B.size(), 0); for (int i = 0; i < A.size(); i++) { int t = 0; for (int j = 0; j < B.size() || t; j++) { if (j < B.size()) t += A[i] * B[j]; t += C[i + j]; C[i + j] = t % 10; t /= 10; } } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 4. 大整数除法 C++ 代码: int cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() < B.size() ? -1 : 1; for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] < B[i] ? -1 : 1; } return 0; } vector<int> div(vector<int> &A, int b, int &r) { vector<int> C; r = 0; for (int i = A.size() - 1; i >= 0; i--) { r = r * 10 + A[i]; C.push_back(r / b); r %= b; } reverse(C.begin(), C.end()); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } vector<int> div(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = A.size() - 1; i >= 0; i--) { C.insert(C.begin(), A[i]); while (cmp(C, B) >= 0) { vector<int> t = sub(C, B); C = t; } } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 5. 高精度开方 C++ 代码: int cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() < B.size() ? -1 : 1; for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] < B[i] ? -1 : 1; } return 0; } vector<int> sqrt(vector<int> &A) { vector<int> C; if (A.size() % 2 == 1) A.push_back(0); for (int i = A.size() - 2; i >= 0; i -= 2) { int res = 0; for (int j = 9; j >= 0; j--) { vector<int> t = mul(C, 20); t.push_back(j * j); if (cmp(t, A) <= 0) { res = j; C.push_back(j); break; } } } reverse(C.begin(), C.end()); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 6. 高精度取模 C++ 代码: int mod(vector<int> &A, int b) { int r = 0; for (int i = A.size() - 1; i >= 0; i--) { r = r * 10 + A[i]; r %= b; } return r; } vector<int> mod(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = A.size() - 1; i >= 0; i--) { C.insert(C.begin(), A[i]); while (cmp(C, B) >= 0) { vector<int> t = sub(C, B); C = t; } } return C; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值