Day 4 上午
内容提要
进制转换
高精度
数论:筛法,gcd/exgcd,逆元
进制转换
10=2^3+2^0=1010(2)
10=3^2+3^0=101(3)
10进制x-->k进制:短除法

k进制x-->10进制:根据定义转换
XnXn-1Xn-2....X0(k)
=Xn*k^n+Xn-1*k^(n-1)+....+X0*k^0
计算机中常用的进制:2,8,10,16
c++中给变量赋一个二进制值:加一个前导0
int a=01001---a=9
十六进制int a=0x1001=16^3+16^0=4097
十六进制中:a--10,b--11,c--12,d--13,e--14,f--15
0x3f3f3f3f=3*16^7+15*16^6+3*16^5+...
高精度:竖式加减乘除法
存储:用一个数组存他的每一位(反着存)
因为如果正着存的话数位就不能对齐了
先写一个int的版本,然后把int全部替换为高精
我们希望写一个好的高精模板,使得这个东西可以直接用
面向对象的编程方法(其实就是模块化,用很多函数)
我们先设一个结构体
struct gaojing
{
int z[];//用来存这个数的数组
int l;//这个高精度是个l位的数
};
这里很坑的点就是对不同的编译器版本,结构体里的数会不一样
比如dev本地的版本会全都赋值0,
但是这显然是不对的,因为0是个n位的数
怎么初始化?
结构体的构造函数,就是每一次声明一个变量的时候调用一次
struct gaojing
{
int z[];//用来存这个数的数组
int l;//这个高精度是个l位的数
gaojing()
{
l=;
memset(z,,sizeof(z));//构造函数
}
};
已经非常接近线性筛了
要实现什么运算?+-*/%
<,<=,>,>=,==,!=
cin>>,cout<<
重载运算符
两个高精计算,返回高精值
gaojing operator + (gaojing a,gaojing b)
{
bulabula
return ans;
}
但是这样写会有问题
(惊不惊喜,意不意外,刺不刺激
c++再调用函数时,如果没有取地址符&
做了一个备份再调用
比如你设了一个x
调用f(x)时先给x做一个备份x',然后把x'传给x
如果加上&,就是直接把x传给它
这里如果拷贝一个超大的高精度的数组,就有可能会tle
所以我们加上取地址符&
gaojing operator + (gaojing &a,gaojing &b)
{
bulabulabula
return ans;
}
但其实这样还有问题
(惊不惊喜,意不意外,刺不刺激
因为比如你手抖把a改了,那么a原本的值就会变
所以我们再加上一个const
而且如果你想要调用stl,就必须要加上const
gaojing operator + (const gaojing &a,const gaojing &b)
{
bulabulabula return c;
}
这样就好了
完整的重载
gaojing operator + (const gaojing &a,const gaojing &b)
{
gaojing c;
int l=max(a.l,b.l);
for(int i=;i<l;i++)
{
c.z[i]+=a.z[i]+b.z[i];
c.z[i+]+=c.z[i]/;
c.z[i]=c.z[i]%;
}//模拟竖式的运算过程
if(c.z[l]!=)l++;//看看是否还有进位
c.l=l; return c;
}
接下来是cin和cout的重载
cin:
friend istream& operator>>(istream&cin,gaojing &a)
{
static char s[];//static静态变量
cin>>s;
int l=strlen(s);//算长度
for(int i=;i<l;i++)
a.z[i]=s[l-i-]-'';
//把读进来的字符串存储
a.l=l;
return cin;//要求返回cin
}
其中static类似于全局变量
不能在函数里边开数组的局部变量
如果要开的话就要加static
friend:友元函数 istream:读入流 ,用cin这个读入函数把它读入到a中
用字符串读入
第一行和最后一行当做模板记就可以
cout:
friend ostream& operator<<(ostream&cin,const gaojing &a)
{
for(int i=a.l-;i>=;i--)
cout<<a.z[i]; return cout;
}
注:这个东西要放到结构体内,因为有友元函数(虽然我不知道为什么,但是记住就好了)
完整的就是这样:
struct gaojing
{
int z[];
int l;
gaojing()
{
l=;
memset(z,,sizeof(z));
}
friend istream& operator>>(istream&cin,gaojing &a) {
static char s[];
cin>>s;
int l=strlen(s);
for(int i=;i<l;i++)
a.z[i]=s[l-i-]-'';
a.l=l; return cin;
} friend ostream& operator<<(ostream&cin,const gaojing &a)
{
for(int i=a.l-;i>=;i--)
cout<<a.z[i]; return cout;
}
};
下面是高精度乘法
同样是模拟竖式计算
gaojing operator * (const gaojing &a,const gaojing &b)
{
gaojing c;
for(int i=;i<a.l;i++)
for(int j=;j<b.l;j++)
c.z[i+j]+=a.z[i]*b.z[j];
//第i位和第j位相乘贡献第i+j位 c.l=a.l+b.l;//位数最多是这些
for(int i=;i<c.l;i++)
{
c.z[i+]+=c.z[i]/;
c.z[i]=c.z[i]%;
}//处理进位
while(c.l>&&c.z[c.l]==)
c.l--;
c.l++;//找到第一个不等于0的位置,就是他的最高位
//因为从0开始,所以位数+1 return c;
}
数论:
π(x)≈x/log x
质数
只有1和自身作为因子的数叫做质数
以π(x)表示不超过 x 的素数的个数,可以证
lim π(x) ln x ÷ x = 1
最常见的判断素数的方法:
bool is_prime(int x)
{
if(x<=)return false;
for(int a=;a<x;a++)
if(x%a==) return false;
return true;
}
复杂度O(x)
可以做一些优化
x=a*b>=a*a,a<=b,x>=a^2,a<=√x
bool is_prime(int x)
{
if(x<=)return false;
for(int a=;a*a<x;a++)
if(x%a==) return false;
return true;
}
复杂度降到O(√n)
但是如果我们想要求一个区间之内的所有质数呢?
一个一个代进去显然会tle
复杂度O(n√n)
所以我们需要一种更快的方法
筛法
两种非线性的算法:
1.
我们枚举所有数,并把它的所有倍数标记成合数
复杂度O(n logn)
n/2+n/3+n/4+....+n/n
≈n(1+1/2+1/3+...+1/n)
≈n log n
for(a=;a<=n;a++)
for(int b=+;b<=n;b+=a)
not_prime[b]=true;
2.
实际上,我们只需要筛掉质数的倍数,因为一个合数的倍数一定是它的质因子的倍数
for(a=;a<=n;a++)
if(not_prime[a]=false)
for(int b=+;b<=n;b+=a)
not_prime[b]=true;
复杂度O(n loglog n)
已经非常接近线性筛了
线性筛就是保证每个数只被他最小的质因子筛掉
这样复杂度就降到O(n)了
代码:
memset(not_prime,,sizeof(not_prime));//初始化为都是质数
not_prime[]=true;//1不是质数
for(int i=;i<=n;i++)
{
if(!not_prime[i]) prime[++prime_count]=i;
//如果i还没有被标记为不是质数 ,就把i加到质数表里面
for(int j=;j<=prime_count;j++)
{
if(prime[j]*i>n) break;//枚举i的质数倍
not_prime[prime[j]*i]=true;
if(i%prime[j]==) break;
//如果i是第j个质数的倍数,就跳出循环
//因为i有prime[j]这个因子,再枚举prime[j]就会变大
//break掉就可以保证一定是被它的最小质因子筛掉
}
}
用来处理积性函数
最大公因子
gcd(a,b)=max (x|a,x|b)
gcd(121,1001)=11
辗转相除法
gcd(a,b)=gcd(b,a%b)
int gcd(int a,int b)
{
if(b==) return a;//gcd(a,0)=a
else return gcd(b,a%b);
}
c++自带的求最大公因数的__gcd(双下划綫),但是最好不要用
gcd(a,b)=g
==>ax+by=g(x,y∈Z)
如:
gcd(30,12)=6
==>1*30-2*12=6
==>-1*30+3*12=6
显然结果有无数组
已经知道gcd(a,b)=g
求一组ax+by=g解
拓展欧几里得算法:

不管进行到那一层,最大公约数都是g
也就是在每一层都可以找到这样的x,y
显然最后一层是最好找的
一定有1*g+0*0=g
然后考虑一层一层的推上去
我们把a%b换一种写法,写成带余除法的形式
余数=被除数-除数*商
xb+y(a-a/b*b)=g(/是下取整)
拆开括号合并同类项
ya+(x-y*(a/b))b=g
而上一层是x'a+y'b=g
所以x'=y,y'=x-y*(a/b)

int exgcd(int a,int b,int &x,int &y)
{
if(b==)//到了最底层
{
x=,y=;//这是一组解
return a;//最大公因数
}
else
{
int g=exgcd(b,a%b,x,y);
int t=x;
x=y,y=t-a/b*x;//x'=y,y'=x-y*(a/b)
return g;
}
}
逆元
希望能边乘边除边取模得到模运算的正确结果
费马小定理:
对于质数p,任取一个1~p-1的数
x^(p-1)%p=1
两边同时除以x
x^(p-2)%p=(1/x)%p
也就是在取模意义下,a/b=a*(1/b)=a*b^(p-2)(mod p)(改符号)
b^(p-2)就是b的逆元
当p不是质数时,需要用到欧拉定理
x^(φ(m))=1(mod m)改符号
φ(m)表示1~m中有多少个数和m互质
求φ的公式
将m分解质因数
m=p1^k1*p2^k2......*pn^kn
φ(m)=m*(1-1/p1)(1-1/p2)....(1-1/pn)
当p为质数时,φ(p)=p-1
所以费马小定理就是欧拉定理的拓展
当m不是质数时,除以x等于乘x^(φ(m)-1)
Day 4 上午的更多相关文章
- SSH-Struts第三弹:传智播客视频教程第一天上午的笔记
一. 框架概述1.三大框架 : 是企业主流 JavaEE 开发的一套架构 Struts2 + Spring + Hibernate 2. 什么是框架?为什么要学框架 ?框架 是 实现部分功能的代码 ( ...
- JAVA判断当前时间是上午am还是下午pm
//结果为"0"是上午 结果为"1"是下午 public class GregorianTest { public static void main(Strin ...
- PKUSC 模拟赛 day2 上午总结
今天上午考得不是很好,主要还是自己太弱QAQ 开场第一题给的图和题意不符,搞了半天才知道原来是走日字形的 然后BFS即可 #include<cstdio> #include<cstr ...
- PKUSC 模拟赛 day1 上午总结
思考了一下第二题,觉得有无数种乱搞做法 类似什么bitset压位,MCS染色之类奇怪的做法 然而都是玄学正确性或者玄学复杂度 先放题解把 第一题显然具有单调性,二分就可以啦 O(nlogn),貌似输出 ...
- 第一天上午——HTML网页基础知识以及相关内容
今天上午学习了HTML基础知识以及相关内容,还有DW的基本使用方法. HTML(HyperText Markup Language):超文本标记语言,超文本:网页中除了包含文本文字之外,还包含了图片, ...
- 九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <init> 严重: The ResourceConfig instance does not contain any root resource classes.
Tomcat启动错误:九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <i ...
- 夏令营提高班上午上机测试 Day 2 解题报告
那一天,日照一中夏令营数据结构提高班的同学们终于想起了,被Day2上午的三道题支配的恐惧…… 是的..这一天的题有点难想.. 本来打算前天写这篇随笔,然而前天在机房和同学打luogu月赛…… 昨天 ...
- Day 1 上午
唉,上午就碰到一个开不了机的电脑,白白浪费了半个小时,真的难受QwQ POINT1 枚举 枚举也称作穷举,指的是从问题所有可能的解的集合中一一枚举各元素. 用题目中给定的检验条件判定哪些是无用的,哪些 ...
- 云栖大会day2总结 上午
第二天上午主要是参与了开发者专场 上 09:00-09:40 线上线下融合时代的工程师成长 李佩 饿了么高级算法总监 09:40-10:20 如何统一阿里巴巴代码规范:探寻工程师文化之路 玄坛 阿里巴 ...
- iOS 根据时间戳计算聊天列表的时间(上午/下午)
把时间戳转成聊天时间(上午 10:00 . 昨天 14:00 . 3月15日 15:00) +(NSString*)ChatingTime:(NSString *)timestring{ int ...
随机推荐
- 最小的VIM操作指南
最小VIM操作指南 vim的操作命令非常多,为了能开始工作,必须学会一个最小的vim操作集合,这里做个总结. 1.插入.追加.插入新行 i:在当前光标所在字符的前面插入,当前字符及其后面的字符后撤 a ...
- docker 制作本地镜像
docker commit 55ddf8d62688 py_wb # 容器ID, 容器名称tag py_wb IP地址:5000/my-web:20180511 # 远程registory地址 我的镜 ...
- Mac mysql-忘记数据库密码
第一步: 关闭mysql服务:苹果->系统偏好设置最下边点mysql 在弹出页面中关闭mysql服务(点击stop mysql server) 第二步: 进入终端输入:cd /usr/local ...
- 用插件NPOI读写excel
1.用插件NPOIusing NPOI.SS.UserModel;using NPOI.XSSF.UserModel;using NPOI.HSSF.UserModel; public class E ...
- 246. Strobogrammatic Number 上下对称的数字
[抄题]: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at u ...
- 安装CentOS 6网络配置问题
安装CentOS 6网络配置问题 今天决定把家中的CentOS从5升级至6.但安装完CentOS 6.2之后发现eth0没有像往常一样通过DHCP自动获取IP.打开“/etc/sysconfig/ne ...
- pip指定安装包版本
pip是目前最好用的python包关系工具,没有之一. 1.版本范围符号:==.>=.<=.>.<. 2.单个安装示例: 1 2 3 pip install cchardet ...
- 基本滤波算法比较 (转载http://blog.sina.com.cn/s/blog_69f2aa5a01014du5.html)
最近在做关于数据采集方面的东西,这就不免涉及到了滤波的算法,在网上找到了关于几种算法的比较. 数字滤波方法有很多种,每种方法有其不同的特点和使用范围.从大的范围可分为3类. 1.克服大脉冲干扰的数字滤 ...
- 设计模式09: Decorator 装饰模式(结构型模式)
Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...
- 跨域Ajax请求(jQuery JSONP MVC)
通过jQuery的$.ajax方法发送JSONP请求 js代码 <script type="text/javascript"> function jsonptest2( ...