为什么偏爱mod 1e9+7呢?using namespace std又是什么?

欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

突然想到了,就查了一下~

一.mod 1e9+7

相信在算法题目中,大家遇到过很多很多次这样的情况:

 

由于结果可能较大,请将结果mod 1e9+7,即mod 1000000007 。

or

( a * b ) % c = [ ( a % c ) * ( b % c ) ] % c ,而这个c最常见的还是1e9+7。

每当数字结果是比较大的时候,我们总是喜欢mod 1e9+7,那么你知不知道为什么偏偏喜欢

mod 1e9+7 而不是别的数呢?

今天忽然想到了这个问题,于是查了一下资料,参考材料较多,恕不能一一列出,在此感谢度娘和各位dalao~~

 

大概≖‿≖✧是因为:

≖‿≖✧是因为:

≖‿≖✧因为:

1)减少冲突。

       首先,1e9+7是一个大的数,int32位的最大值为2147483647,所以对于int32位来说1000000007足够大int64位的最大值为2^63-1,对于1000000007来说它的平方不会在int64中溢出所以在大数相乘的时候,因为(a∗b)%c=((a%c)∗(b%c))%c,所以相乘时两边都对1000000007取模,再保存在int64里面不会溢出 。◕‿◕。

       其次,1e9+7是一个质数,在模素数p的情况下a*n(a非p的倍数)的循环节长为p,这是减少冲突的一个原因。另一方面模素数p的环是无零因子环,也就是说两个非p倍数的数相乘再模p不会是零(如果是0的话,在多个数连乘的情况下会大大增加冲突概率)。比如说如果所有的结果都是偶数…你模6就只可能出现0, 2, 4这三种情况…但模5还是可以出现2, 4, 1, 3这四(4=5-1)种情况的… hash表如果是用取模的方法也要模一个大质数来减少冲突,出题人也会这样来 希望减少你“蒙对“的概率。

2)模1e9+7相加不爆int,相乘不爆long long

3)允许“除法”操作(乘以乘法逆元)

        就是模素数所成的环还是个域,因而允许“除法”操作(乘以乘法逆元),模非素数就没有这个性质。
        一般来说x的选取只要10^x+7保证比初始输入数据的范围大就可以了。比如有些数据范围小的题为了避免用long long而把模数设定为10007。至于为什么要用10^x+7,大概是因为这种patten多为素数而又比较好记吧。

4)出题人的本意不在高精度

       首先有很多题目的答案是很大的,然而出题人的本意也不是让选手写高精度或者Java,所以势必要让答案落在整型的范围内。那么怎么做到这一点呢,对一个很大的质数取模即可(自行思考为什么不是小数)。那么如果您学过哈希表的设计的话,应该知道对质数取模的话,能尽可能地避免模数相同的数之间具备公因数,来达到减少冲突的目的。那么有个很大的且好记的质数1e9+7(包括它的孪生素数1e9+9)。

二.using namespace std

咱们在写完头文件的时候,都会写上using namespace std; 这一句,想最初学快排的时候,我们只知道用快排什么的,都要在头文件下面加上这一句,才能使用。那么可曾想过,这一行是做什么的呢?为什么要加这一行呢?

度娘回答如下:

std 是一个命名空间 .. 

不同的命名空间可以有相同的类名被定义 ..

using namespace std;

就是指明下面的程序使用std,如果不用这句指明的话就要用std::string(string是std空间中定义的也可以在全局空间中定义,只要名字空间不一样即可....)

否则可以默认名字空间中有std,便不用std::来修饰

它是C++新标准中有的,解决多人作编大程序时名字冲突问题。比如A B两个班都有叫张三的人,你要使用A班的张三,必然要先指明是A班这个名字空间(namespace),然后你对张三的所有命令才能达到你的预想,不会叫错人。

如果你用#include<iostream.h>就不需写这句话(旧标准)。但是如果你用#include<iostream>就必须要写。

所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
一 :

<iostream>和<iostream.h>是不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。

后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。

因此,当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespacestd;这样才能正确使用cout。

二:

所谓namespace,是指标识符的各种可见范围。

C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:

1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:

std::cout << std::hex<< 3.4<< std::endl;

2、使用using关键字。

using std::cout;
using std::endl;

以上程序可以写成

cout << std::hex<< 3.4<< endl;

3、最方便的就是使用using namespace std;

例如:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:

cout << hex<< 3.4<< endl;

因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。

        所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。

命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"

using namespacestd;实际上就是告诉编译器,你类型是什么,在哪能找到。

常用的是using namespace std,就是说用C++的标准名字空间。

你也可以引用你自己的名字空间。比如说:

import "C:\\MyTest\\test.tlb"
using namespace CMyTest

就可以引用CMyTest内的各个类型名

看C++ prime
---------------------------------------------------------------

声明该文件使用C++标准库吧!
比如
#include <iostream>
using namespace std;
void main()
{
   cout<< "hello!"<< endl;
}

如果不用using namespace std;这句,那么
std::cout << "hello!"<<endl;
这是名字空间的问题!具体参看有关书籍吧,新版的C++ 书应该都有介绍的!

---------------------------------------------------------------

using 指示符!
这是个名字空间问题,是标准C++引入的新概念!
具体在《C++Primer》第8.6节有详细说明!
---------------------------------------------------------------

因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。

所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。
---------------------------------------------------------------

名字空间,实质上也是为了方便程序在不同平台上正确的运行。
---------------------------------------------------------------

namespace是为了解决C++中的名字冲突而引入的。
什么是名字冲突呢?比如,在文件x.h中有个类MyClass,
在文件y.h中也有个类MyClass,而在文件z.cpp中要同时
引用x.h和y.h文件。显然,按通常的方法是行不能的,
那怎么办呢?引入namespace即可。

参考材料较多,恕不能一一列出,再次感谢度娘和各位dalao~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

猜你喜欢

转载自blog.csdn.net/lxt_lucia/article/details/81210762