清北学堂(2019 5 1) part 4

今天讲数论

1.进制问题(将n转换成k进制数):

  1.方法:短除法

   将n/k,保存,将商当做新的n,将余数保存,直到商为0,将余数(包括0),倒序输出,即得n的k进制数

2.关于高精四则运算(我本以为不用怎么整的):

   举个加和乘的例子...

  众所周知,a+b problem是最简单的红题,再加个*也无伤大雅,代码如下(没文件头):

int main(){
    int a,b;
    cin>>a>>b;
    cout<<a*b;
    return 0;
}

  直到你加了这些东西:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct nu{
 4     int a[100005];
 5     int l;
 6     nu(){
 7         l=1;
 8         memset(a,0,sizeof(a));
 9     }
10     friend istream& operator>>(istream &cin,nu &x){  //意思是:重载>>(用于cin,读到x里面)
11         static char s[100005];
12         cin>>s;
13         int l=strlen(s);
14         for(int i=0;i<=l;i++)
15             x.a[i]=s[l-i-1]-'0';
16         x.l=l;
17         return cin;
18     }
19     friend ostream& operator<<(ostream &cout,const nu &x){   //与上面大同,多了个const,在于使x值在输出前后值相同
20         for(int i=x.l-1;i>=0;i--)
21             cout<<x.a[i];
22     }
23 };
24 nu operator+(const nu &x,const nu &y){    //重载+
25     nu ans;
26     int len=max(x.l,y.l);
27     for(int i=0;i<len;i++)
28         ans.a[i]+=x.a[i]+y.a[i];
29     for(int i=0;i<len;i++){
30         if(ans.a[i]>=10){
31             int now=ans.a[i]/10;
32             ans.a[i+1]+=now;
33             ans.a[i]%=10;
34         }
35         while(ans.a[len+1]) len++;
36     }
37     ans.l=len;
38     return ans;
39 }
40 nu operator*(const nu &x,const nu &y){    //重载*用了非常简单而经典的高精算法
41     nu ans;
42     for(int i=0;i<x.l;i++)
43         for(int j=0;j<y.l;j++)
44             ans.a[i+j]+=x.a[i]*y.a[j];
45     ans.l=x.l+y.l;
46     for(int i=0;i<ans.l;i++){
47         ans.a[i+1]+=ans.a[i]/10;
48         ans.a[i]%=10;
49     }
50     while(ans.l>0&&!(ans.a[ans.l]))
51         ans.l--;
52     ans.l++;
53     return ans;
54 }
55 int main(){
56     nu a,b;
57     cin>>a>>b;
58     cout<<a*b;
59     return 0;
60 }

  6-9行是构造函数,用于memset

  10-22是重载cin与cout,背过就好

  加const的原因是进行运算的值由符号返回,而从不是变量本身,所以没有赋值的话不能改变变量的值,也更方便电脑理解,可以看到stl里面好多函数用了const

  至于&符号,用因如下:

  每次用函数运算时,每个函数形如 f(int n),都要把用的变量“n”的值拷贝一份进行运算,如果引用数组就更慢,还更占内存,用了&符号意在免去拷贝操作,直接引用其值,

  (反正有了const不用怕数值变化)这就算一个优化

  后面一直到主函数之前都是重载运算符

3.关于素数(又是各种筛法)

  粘下模板:

  1.埃氏筛:

#include<bits/stdc++.h>
using namespace std;
bool no[10005]={1,1};
int pri[10000];
int tot;
inline void p(int t){
    for(int i=1;i<=t;i++)
        if(!no[i]){
            pri[++tot]=i;
            for(int j=i+i;j<=t;j+=i)
                no[j]=1;
        }
}
int n;
int main(){
    scanf("%d",&n);
    p(n);
    for(int i=1;i<=tot;i++)printf("%d\n",pri[i]);
    return 0;
}

  欧拉筛(线性筛):

#include<bits/stdc++.h>
using namespace std;
bool no[10005];
int pri[10000];
int tot;
int n;
inline void p(int n){
    for(int i=2;i<=n;i++){
        if(!no[i])
            pri[++tot]=i;
        for(int j=1;j<=n&&i*pri[j]<=n;j++){
            no[i*pri[j]]=1;
            if(!(i%pri[j])) break;
        }
    }
}
int main(){
    scanf("%d",&n);
    p(n);
    for(int i=1;i<=tot;i++)printf("%d\n",pri[i]);
    return 0;
}

  3.exgcd:

#include<bits/stdc++.h>
using namespace std;
int a,b,x,y;
inline int exgcd(int a,int b,int &x,int &y){      //利用性质gcd(a,b)=gcd(b,a%b)
    if(!b){
        x=1;
        y=0;
        return a;
    }int g=exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=(t-(a/b)*x);
    return g;
}
int main(){
    cin>>a>>b;
    exgcd(a,b,x,y);
    if(x<0) x+=b;
    cout<<x;
    return 0;
}

  练多了不解释...

  下午考试了..我..应该..大概不会爆零

 

转载于:https://www.cnblogs.com/648-233/p/10800009.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值