数学知识——常用模板

技巧

切换编译器c++版本

-std=c++11

 万能头

#include <bits/stdc++.h>

cin cout加速 

ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

全排列函数

 next_permutation(a,a+n);

stl的优先队列

priority_queue<PII,vector<PII>,greater<PII>>

string的常用方法

    string a;
    cin>>a;

//字符串查找
    if(a.find("yu",8)!=a.npos)
        cout<<"Yes";
    else
        cout<<"No";

//字符串截取
    cout<<a.substr(1,5);
//从下标从1的位置开始向后截取5个


getline(cin,s);
整行输入

//高精度加法

数组模拟版本

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 1e18;
int na[N], cnta;
int nb[N], cntb;
int f[N];
int n, t, s, m, x;
void add() {
  for (int i = n; i >= 1; i--) {
    na[i - 1] += (na[i] + nb[i]) / 10;
    na[i] = (na[i] + nb[i]) % 10;
  }
}
signed main() {
  string a, b;
  cin >> a >> b;
  n = a.length();
  m = b.length();
  if (n < m) {
    string t = a;
    a = b;
    b = t;
    int tp = n;
    n = m;
    m = tp;
  }
  int tmp = abs(n - m);
  for (int i = 0; i < n; i++) {
    na[i + 1] = a[i] - '0';
  }
  for (int i = 0; i < m; i++) {
    nb[i + 1 + tmp] = b[i] - '0';
  }
  add();
  if (na[0] != 0) {
    cout << na[0];
  }
  for (int i = 1; i <= n; i++) cout << na[i];
  return 0;
}

vector版本

#include<iostream>
using namespace std;
#include<vector>
const int n=1e6+10;
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;
}
int main()
{
string a,b;
vector<int >A,B;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i-- ) A.push_back(a[i]-'0');
for(int i=b.size()-1;i>=0;i-- ) B.push_back(b[i]-'0');


auto C=add(A,B);
for(int i=C.size()-1;i>=0;i--){
    printf("%d",C[i]);
}
    return 0;
}

高精度减法

数组模拟

// Problem: 选数异或
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/4648/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 1e18;
int na[N], cnta;
int nb[N], cntb;
int f[N];
int n, t, s, m, x;
void add() {
  for (int i = n; i >= 1; i--) {
    if (na[i] < nb[i]) {
      na[i - 1] -= 1;
      na[i] = na[i] + 10 - nb[i];
    } else
      na[i] = na[i] - nb[i];
  }
}
signed main() {
  string a, b;
  cin >> a >> b;
  n = a.length();
  m = b.length();
  int flag = 1;
  if (n < m) {
    flag = -1;
  }
  if (n < m) {
    string t = a;
    a = b;
    b = t;
    int tp = n;
    n = m;
    m = tp;
  }
  if (n == m) {
    for (int i = 0; i < n; i++) {
      if (a[i] > b[i])
        break;
      else if (a[i] < b[i]) {
        flag = -1;
        string t = a;
        a = b;
        b = t;
        int tp = n;
        n = m;
        m = tp;
        break;
      }
    }
  }
  int tmp = abs(n - m);
  for (int i = 0; i < n; i++) {
    na[i + 1] = a[i] - '0';
  }
  for (int i = 0; i < m; i++) {
    nb[i + 1 + tmp] = b[i] - '0';
  }
  add();
  if (flag < 0) cout << "-";
  int i = 1;
  while (na[i] == 0) i++;

  for (; i <= n; i++) cout << na[i];
  return 0;
}

vector模拟

#include <iostream>
using namespace std;
#include <vector>
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];
}

vector<int> sub(vector<int>& A, vector<int>& B) {
  vector<int> C;
  int t = 0;
  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();  //去前导零,保证只剩一位时输出10
  return C;
}
int main() {
  string a, b;
  vector<int> A, B;
  cin >> a >> b;
  for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
  for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');

  if (cmp(A, B)) {
    auto C = sub(A, B);
    for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
  } else {
    auto C = sub(B, A);
    printf("-");
    for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
  }
  return 0;
}

高精度乘低精度乘法

vector模拟版本

//自研版本
vector<int> add(vector<int> v, ll b) {
  int tmp = 0;
  for (int i = 0; i < v.size(); i++) {
    int t = v[i] * b / 10;
    v[i] = (v[i] * b + tmp) % 10;
    tmp = t;
  }
  while (tmp) {
    v.push_back(tmp % 10);
    tmp /= 10;
  }
  return v;
}

//acwing版本
vector<int> mul(vector<int>& a, int b) {
  vector<int> c;
  int t = 0;
  int n = a.size();
  for (int i = 0; i < n || t; i++) {
    if (i < n) t += a[i] * b;
    c.push_back(t % 10);
    t /= 10;
  }
  return c;
}

高精度乘高精度(数组模拟版本)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int x[N], y[N];
string a, b;
int c[N];
int len;
void mul() {
  len = a.size() + b.size() + 1;
  for (int i = 0; i < len; i++) {
    for (int j = 0; j <= i; j++) c[i] += x[j] * y[i - j];
    if (c[i] >= 10) {
      c[i + 1] += c[i] / 10;
      c[i] %= 10;
    }
  }
  while (c[len] == 0) len--;
}
int main() {
  cin >> a >> b;
  for (int i = a.size() - 1; i >= 0; i--) x[a.size() - 1 - i] = a[i] - '0';
  for (int i = b.size() - 1; i >= 0; i--) y[b.size() - 1 - i] = b[i] - '0';
  mul();
  for (int i = len; i >= 0; i--) cout << c[i];

  return 0;
}

vector版本

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
vector<int> x, y;
string a, b;
int c[N];
int len;
void mul() {
  len = a.size() + b.size() + 1;
  while (x.size() < len) x.push_back(0);
  while (y.size() < len) y.push_back(0);
  //这里是为了保证下面取x[j]和y[i-j]不会报re
  //数组模拟时长度足够长所以不需要考虑re的问题。
  for (int i = 0; i < len; i++) {
    for (int j = 0; j <= i; j++) c[i] += x[j] * y[i - j];
    if (c[i] >= 10) {
      c[i + 1] += c[i] / 10;
      c[i] %= 10;
    }
  }
  while (c[len] == 0) len--;
}
int main() {
  cin >> a >> b;
  for (int i = a.size() - 1; i >= 0; i--) x.push_back(a[i] - '0');

  for (int i = b.size() - 1; i >= 0; i--) y.push_back(b[i] - '0');
  // for (int i = 0; i < x.size(); i++) cout << x[i];

  mul();
  for (int i = len; i >= 0; i--) cout << c[i];

  return 0;
}

//试除法求质数

bool is_prime(int n)
{
    if(n<2) return false;
    for(int i=2;i<sqrt(n);i++)
    if(n%i==0)return false;
    
    return true;
}

 //埃氏筛法(1~n之间的质数)

void prime(int n)
{
    memset(st,0,sizeof st);
    for(int i=2;i<=n;i++)
    {
        if(st[i]) continue;
        cout<<i<<endl;//i为质数
        for(int j=i;j<=n/i;j++)st[i*j]=true;
    }
}

//线筛法求质数

const int N=1e6+10;
bool st[N];
int primes[N],cnt;
void get_primes(int n)
{
    memset(st,0,sizeof st);
    cnt=0;
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) primes[++cnt]=i;
        for(int j=1;primes[j]<=n/i;j++)
        {
            st[primes[j]*i]=true;
            if(i%primes[j]==0)break;//
        }
    }
}

//质因数分解
 

void div(int n)
{
    m=0;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            p[++m]=i,cnt[m]=0;
            while(n%i==0)n/=i,cnt[m]++:
        }
    }
    if(n>1)//n自身或最后剩的n也是质数的情况
    p[++m]=n,cnt[m]=1;
}
    

求最大公约数

欧几里得算法:

int get_gcd(int a,int b)
{
    return b?get_gcd(b,a%b):a;
}

定理:任意的a,b属于N,都有 gcd( a , b ) * lcm ( a , b ) = a * b;

           任意的a,b属于N,都有gcd( 2 * a , 2 * b) = 2 * gcd( a , b );

更相损减术:任意的a,b(a>=b) ,都有gcd(a,b)=gcd(b,a-b)=gcd(a,a-b)

扩展欧几里得算法:

应用方面:给定两个非零整数a,b,求一组整数x,y使得ax+by = gcd(a,b)成立,在欧几里得算法中,当b==0时就会返回a,此时a就是最大公约数,此时有x=1,y=0使得,ax+by=gcd(a,0)成立。

因为有ax+by==gcd(a,b)==gcd(b,a%b)==bx+(a%b)y

故ax+by==bx+(a%b)y

由此可以推出

ax+by==bx+(a-b(a/b))y==ay1+b(x1-(a/b)*y1)

因此可以令

x=y1;

y=x1-(a/b)*y1;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
int exgcd(int a,int b,int &x,int &y)
{
    if(b==0) { x=1,y=0;return a;}
    int d=exgcd(b,a%b,x,y);
    int z=x;
    x=y;
    y=z-y*(a/b);
    return  d;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int a,b,x,y;
        scanf("%d%d",&a,&b);
        exgcd(a,b,x,y);
        printf("%d %d\n",x,y);
    }
     return 0;
}

......................................................分界线——————————

欧拉函数:f(n)=1~n中与n互质的数的个数;

互质:gcd(n,i)=1 ,最大公约数为1; 

性质1:任意n>1,1~n中与n互质的数和为n*f(n)/2;

性质2:若a,b互质,则f(a*b)=f(a)*f(b)

代码:

int phi(int n)
{
    int ans=n;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
      {
     ans=ans/i*(i-1);
      while(n%i==0) n/=i;
      }
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值