#include
using namespace std;
#define LL long long
const int N = 5e6 + 2;
bool np[N];
int prime[N], pi[N];
int getprime()
{
int cnt = 0;
np[0] = np[1] = true;
pi[0] = pi[1] = 0;
for(int i = 2; i < N; ++i)
{
if(!np[i]) prime[++cnt] = i;
pi[i] = cnt;
for(int j = 1; j <= cnt && i * prime[j] < N; ++j)
{
np[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
return cnt;
}
const int M = 7;
const int PM = 2 * 3 * 5 * 7 * 11 * 13 * 17;
int phi[PM + 1][M + 1], sz[M + 1];
void init()
{
getprime();
sz[0] = 1;
for(int i = 0; i <= PM; ++i) phi[i][0] = i;
for(int i = 1; i <= M; ++i)
{
sz[i] = prime[i] * sz[i - 1];
for(int j = 1; j <= PM; ++j) phi[j][i] = phi[j][i - 1] - phi[j / prime[i]][i - 1];
}
}
int sqrt2(LL x)
{
LL r = (LL)sqrt(x - 0.1);
while(r * r <= x) ++r;
return int(r - 1);
}
int sqrt3(LL x)
{
LL r = (LL)cbrt(x - 0.1);
while(r * r * r <= x) ++r;
return int(r - 1);
}
LL getphi(LL x, int s)
{
if(s == 0) return x;
if(s <= M) return phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];
if(x <= prime[s]*prime[s]) return pi[x] - s + 1;
if(x <= prime[s]*prime[s]*prime[s] && x < N)
{
int s2x = pi[sqrt2(x)];
LL ans = pi[x] - (s2x + s - 2) * (s2x - s + 1) / 2;
for(int i = s + 1; i <= s2x; ++i) ans += pi[x / prime[i]];
return ans;
}
return getphi(x, s - 1) - getphi(x / prime[s], s - 1);
}
LL getpi(LL x)
{
if(x < N) return pi[x];
LL ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - 1;
for(int i = pi[sqrt3(x)] + 1, ed = pi[sqrt2(x)]; i <= ed; ++i) ans -= getpi(x / prime[i]) - i + 1;
return ans;
}
LL lehmer_pi(LL x)
{
if(x < N) return pi[x];
int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
int b = (int)lehmer_pi(sqrt2(x));
int c = (int)lehmer_pi(sqrt3(x));
LL sum = getphi(x, a) +(LL)(b + a - 2) * (b - a + 1) / 2;
for (int i = a + 1; i <= b; i++)
{
LL w = x / prime[i];
sum -= lehmer_pi(w);
if (i > c) continue;
LL lim = lehmer_pi(sqrt2(w));
for (int j = i; j <= lim; j++) sum -= lehmer_pi(w / prime[j]) - (j - 1);
}
return sum;
}
int main()
{
init();
LL n;
cin>>n;
cout<<lehmer_pi(n)<<endl;//输出n以内有多少个质数,可以输出1e11以内的
return 0;
}
for(int i=0;i<cnt;i++)
{
LL p=primes[i],a=p;
LL s=0;
while(p<=n)s+=n/p,p*=a;
cout<<a<<' '<<s<<endl;
}
void get_primes(int n){
//外层从2~n迭代,因为这毕竟算的是1~n中质数的个数,而不是某个数是不是质数的判定
for(int i=2;i<=n;i++){
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++){//primes[j]<=n/i:变形一下得到——primes[j]*i<=n,把大于n的合数都筛了就
//没啥意义了
st[primes[j]*i]=true;//用最小质因子去筛合数
//1)当i%primes[j]!=0时,说明此时遍历到的primes[j]不是i的质因子,那么只可能是此时的primes[j]
//最小质因子,所以primes[j]*i的最小质因子就是primes[j];
//2)当有i%primes[j]==0时,说明i的最小质因子是primes[j],因此primes[j]*i的最小质因子也就应该是
//prime[j],之后接着用st[primes[j+1]*i]=true去筛合数时,就不是用最小质因子去更新了,因为i有最小
//质因子primes[j]
//退出循环,避免之后重复进行筛选。
if(i%primes[j]==0) break;
}
}
}
void divide(int n){
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
//n不包含任何从2到i-1之间的质因子(已经被除干净了)
//(n%i==0)所以i也不包含何从2到i-1之间的质因子,由质数的定义可知,保证了i是质数
int s=0;
while(n%i==0) n/=i,s++;
cout<<i<<' '<<s<<endl;
}
}
if(n>1) cout<<n<<' '<<1<<endl; //最多只有一个大于根下n的质因子(两个相乘就大于n了)
cout<<endl;
}
将枚举i
直接变为枚举质因子,这里用求约数个数举例
for(int i=0;i<cnt&&primes[i]*primes[i]<=x;i++)
{
if(x%primes[i]==0)
{
int s=0;
while(x%primes[i]==0)
{
s++;
x/=primes[i];
}
res=res*(s+1);
}
}
if(x>1)res=res*2;
常用小结论:
int phi(int x)
{
//公式:num=nnum*(1-1/p_1)*(1-1/p_2)....*(1-1/p_i);
int res=x;
for (int i=2;i<=x/i;i++)
if (x%i==0)//分解质因数
{
while (x%i==0)x/=i;
res=res/i*(i-1);//先除再乘防止爆long long
}
if (x>1)res=res/x*(x-1);
return res;
}
int n;
const int N=1e6+10;
int primes[N],phi[N],cnt;//存N个质数,1~N每个数的欧拉函数
bool st[N];//质数false,合数true
int get_eulers(int n)
{
phi[1]=1; //1的欧拉函数只有一个,如果求小于它本身的与它互质的个数,注释此
for(int i=2;i<=n;i++)
{
if(!st[i])
{ //如果没有被筛掉
primes[cnt++]=i;
phi[i]=i-1; //说明这个数是质数,而质数的欧拉函数为i - 1个
}
for(int j=0;primes[j]<=n/i;j ++)
{
int t=primes[j]*i;
st[t]=true;
if(i%primes[j]==0)
{ //这边上面推导过
phi[t]=phi[i]*primes[j];
break;
}
phi[t]=phi[i]*(primes[j]-1);
}
}
int res=0;
for(int i=1;i<=n;i ++)res+=phi[i]; //把所有数的欧拉函数加起来,也就是答案
return res;
}
map<int,int>mp;//i的指数
int get(int x)
{
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
while(x%i==0)
{
x/=i;
mp[i]++;
}
}
}
if(x>1)mp[x]++;
int res=1;
for(auto x:mp)res=res*(x.y+1);
return res;
}
for(int i=0;i<cnt&&primes[i]*primes[i]<=x;i++)
{
if(x%primes[i]==0)
{
int s=0;
while(x%primes[i]==0)
{
s++;
x/=primes[i];
}
res=res*(s+1);
}
}
if(x>1)res=res*2;
#include
using namespace std;
typedef long long LL;
const int mod=1e9+7;
int t;
int n;
unordered_map<int,int>mp;
void get(int n)
{
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
while(n%i==0)
{
mp[i]++;
n/=i;
}
}
}
if(n>1)mp[n]++;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
get(n);
}
LL res=1;
for(auto x:mp)
{
int a=x.first,b=x.second;
LL t=1;
while(b--)t=(t*a+1)%mod;
res=(res*t)%mod;
}
cout<<res<<endl;
return 0;
}
int n;
const int N=5e4+10,mod=1e9+7;
int primes[N],phi[N],cnt;//存N个质数,1~N每个数的欧拉函数
bool st[N];//质数false,合数true
int a[N];
int get_eulers(int n)
{
phi[1]=1; //1的欧拉函数只有一个,如果求小于它本身的与它互质的个数,注释此
for(int i=2;i<=n;i++)
{
if(!st[i])
{ //如果没有被筛掉
primes[cnt++]=i;
phi[i]=i-1; //说明这个数是质数,而质数的欧拉函数为i - 1个
}
for(int j=0;primes[j]<=n/i;j ++)
{
int t=primes[j]*i;
st[t]=true;
if(i%primes[j]==0)
{ //这边上面推导过
phi[t]=phi[i]*primes[j];
break;
}
phi[t]=phi[i]*(primes[j]-1);
}
}
}
void solve()
{
cin>>n;
unordered_map<int,int>mp;
rep(i,1,n)
{
int x;
cin>>x;
for(int i=0;i<cnt&&primes[i]*primes[i]<=x;i++)
{
if(x%primes[i]==0)
{
int s=0;
while(x%primes[i]==0)
{
s++;
x/=primes[i];
}
mp[primes[i]]+=s;
}
}
if(x>1)mp[x]++;
}
int res=1;
for(auto x:mp)
{
int sum=0;
int num=x.x,s=x.y;
rep(i,0,s)
sum=(sum+qmi(num,i,mod))%mod;
res=(res*sum)%mod;
}
cout<<res<<endl;
}
signed main()
{
io;
int _;_=1;
get_eulers(N-1);
//cin>>_;
while(_--)solve();
}
//for(int i=start;i<=ed;i++)res+=num/i;
int block(int start,int ed,int num)
{
int r=0;
int res=0;
ed=min(ed,num);
for(int i=start;i<=ed;i=r+1)
{
r=min(ed,num/(num/i));
res+=(r-i+1)*(num/i);
}
return res;
}
LL n;
int len=1010;
const int N=1e6+10;
double s[N];
int cnt;
void init(int n)
{
double res=0;
rep(i,1,n*len)
{
res+=1.0/i;
if(i%len==0)s[i/len]+=res;
}
}
double query(int n)
{
int k=n/len;
double sum=s[k];
for(int i=k*len+1;i<=n;i++)sum+=1.0/i;
return sum;
}
struct bint:vector<int>
{
void format();
bint(int n)
{
do push_back(n % 10), n /= 10; while (n);
}
bint(long long n)
{
do push_back(n % 10), n /= 10; while (n);
}
bint(string s)
{
for (int i = s.size() - 1; i >= 0; i --) push_back(s[i] - '0');
}
bint()
{
}
};
istream& operator>>(istream& in, bint& n);
ostream& operator<<(ostream& out, bint n);
bool operator<(bint a, bint b);
bool operator<=(bint a, bint b);
bool operator>(bint a, bint b);
bool operator>=(bint a, bint b);
bool operator==(bint a, bint b);
bool operator!=(bint a, bint b);
bint operator+(bint a, bint b);
bint operator-(bint a, bint b);
bint operator*(bint a, bint b);
bint operator/(bint a, bint b);
bint operator%(bint a, bint b);
template<typename T>
bint operator*(bint a, T b);
template<typename T>
bint operator/(bint a, T b);
template<typename T>
bint operator%(bint a, T b);
template<typename T>
bint operator*(T a, bint b);
bint divmode(bint& a, bint b);
template<typename T>
bint divmode(bint a, T b, T& r);
template<typename T>
void operator+=(T& a, T b);
template<typename T>
void operator-=(T& a, T b);
template<typename T>
void operator*=(T& a, T b);
template<typename T>
void operator/=(T& a, T b);
template<typename T>
void operator%=(T& a, T b);
void operator--(bint& a);
void operator++(bint& a);
void bint::format()
{
while(size() > 1 && back() == 0) pop_back();
}
istream& operator>>(istream& in, bint& n)
{
string s;
in >> s;
n.clear();
for (int i = s.size() - 1; i >= 0; i --) n.push_back(s[i] - '0');
return in;
}
ostream& operator<<(ostream& out, bint n)
{
for (int i = n.size() - 1; i >= 0; i --) out << n[i];
return out;
}
bool operator<(bint a, bint 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 false;
}
bool operator<=(bint a, bint b)
{
return a < b || a == b;
}
bool operator>(bint a, bint b)
{
return !(a <= b);
}
bool operator>=(bint a, bint b)
{
return !(a < b);
}
bool operator==(bint a, bint b)
{
if (a.size() != b.size()) return false;
for (int i = a.size() - 1; i >= 0; i --)
if (a[i] != b[i])
return false;
return true;
}
bool operator!=(bint a, bint b)
{
return !(a == b);
}
bint operator+(bint a, bint b)
{
int t = 0;
bint c;
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(t);
return c;
}
bint operator-(bint a, bint b)
{
if (b > a)
{
cerr << "Error occurs at BigInteger operator-(BigInteger, BigInteger)" << endl;
cerr << "A negative result is produced" << endl;
return a;
}
int t = 0;
bint c;
for (int i = 0; i < a.size() ; i ++)
{
t += a[i];
if (i < b.size()) t -= b[i];
if (t < 0) c.push_back(t + 10), t = -1;
else c.push_back(t), t = 0;
}
c.format();
return c;
}
bint operator*(bint a, bint b)
{
bint c;
c.assign(a.size() + b.size() - 1, 0);
for(int i = 0; i < a.size(); i ++)
for(int j = 0; j < b.size(); j ++)
c[i + j] += a[i] * b[j];
for (int i = 0; i < c.size() - 1; i ++)
if (c[i] >= 10)
c[i + 1] += c[i] / 10, c[i] %= 10;
if (c[c.size() - 1] >= 10) c.push_back(c[c.size() - 1] / 10), c[c.size() - 2] %= 10;
c.format();
return c;
}
bint operator/(bint a, bint b)
{
return divmode(a, b);
}
bint operator%(bint a, bint b)
{
divmode(a, b);
return a;
}
template<typename T>
bint operator*(bint a, T b)
{
bint c;
T 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;
}
c.format();
return c;
}
template<typename T>
bint operator*(T a, bint b)
{
return b * a;
}
template<typename T>
bint operator/(bint a, T b)
{
T r = 0;
return divmode(a, b, r);
}
template<typename T>
T operator%(bint a, T b)
{
T r;
divmode(a, b, r);
return r;
}
bint divmode(bint& a, bint b)
{
if (b == 0)
{
cerr << "Error occurs at BigInteger operator/(BigInteger, BigInteger)" << endl;
cerr << "Divided by zero" << endl;
return a;
}
bint c, d, e;
for (int i = a.size() - b.size(); a >= b; i --)
{
d.clear(), d.assign(i + 1, 0), d.back() = 1;
int l = 0, r = 9, m;
while (l < r)
{
m = l + r + 1 >> 1;
e = b * d * m;
if (e <= a) l = m;
else r = m - 1;
}
a -= b * d * l, c += d * l;
}
return c;
}
template<typename T>
bint divmode(bint a, T b, T& r)
{
bint 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());
c.format();
return c;
}
template<typename T>
void operator+=(T& a, T b)
{
a = a + b;
}
template<typename T>
void operator-=(T& a, T b)
{
a = a - b;
}
template<typename T>
void operator*=(T& a, T b)
{
a = a * b;
}
template<typename T>
void operator/=(T& a, T b)
{
a = a / b;
}
template<typename T>
void operator%=(T& a, T b)
{
a = a % b;
}
void operator--(bint& a)
{
a -= bint(1);
}
void operator++(bint& a)
{
a += bint(1);
}
int main()
{
bint a, b;
cin >> a >> b;
cout << a + b;
return 0;
}
char str[505];
struct BigNum {
int num[505], len;
}A, B, C;
void print(BigNum &x) { //输出大整数x
for(int i = x.len - 1; i >= 0; i--) printf("%d", x.num[i]);
printf("\n");
}
void add(BigNum &x, BigNum &y, BigNum &z) {
z.len = max(x.len, y.len); // 结果最小长度为两者长度最大值
for(int i = 0; i < z.len; i++) z.num[i] = x.num[i] + y.num[i]; // 不进位加法得到初步结果
for(int i = 0; i < z.len; i++)
if(z.num[i] > 9) { // 进行逐位进位
z.num[i + 1] += 1;
z.num[i] -= 10;
}
if(z.num[z.len]) ++z.len; // 判断最高位是否有进位
}
int main() {
// 读取并倒序存储大整数A
scanf("%s", str);
int len = strlen(str);
A.len = len;
for(int i = 0; i < len; i++) A.num[len - i - 1] = str[i] - '0';
// 读取并倒序存储大整数B
scanf("%s", str);
B.len = len = strlen(str);
for(int i = 0; i < len; i++) B.num[len - i - 1] = str[i] - '0';
add(A, B, C); // 计算结果
print(C); // 输出
return 0;
}
#define MAXN 11111
char str[MAXN];
struct BigNum {
int num[MAXN], len;
}A, B, C;
void print(BigNum &x) { //输出大整数x
for(int i = x.len - 1; i >= 0; i--) printf("%d", x.num[i]);
printf("\n");
}
int judge(BigNum &x, BigNum &y) {
// 比较函数 长度长的大,其次从高到低逐位比较,全相同返回0,x>y返回1, x
if(x.len > y.len) return 1;
if(x.len < y.len) return -1;
for(int i = x.len - 1; i >= 0; i--) {
if(x.num[i] > y.num[i]) return 1;
if(x.num[i] < y.num[i]) return -1;
}
return 0;
}
void Minus(BigNum &x, BigNum &y, BigNum &z) {
if(judge(x, y) == -1) {
printf("-");
Minus(y, x, z); //保证被减数为较大的
} else {
z.len = x.len; // 结果最小长度为x长度
for(int i = 0; i < z.len; i++) z.num[i] = x.num[i] - y.num[i]; // 不进位减法得到初步结果
for(int i = 0; i < z.len; i++)
if(z.num[i] < 0) { // 进行逐位退位
z.num[i + 1] -= 1;
z.num[i] += 10;
}
while(z.len > 1 && !z.num[z.len - 1]) --z.len; // 判断最高位是否有退位
}
return ;
}
int main() {
// 读取并倒序存储大整数A
scanf("%s", str);
int len = strlen(str);
A.len = len;
for(int i = 0; i < len; i++) A.num[len - i - 1] = str[i] - '0';
// 读取并倒序存储大整数B
scanf("%s", str);
B.len = len = strlen(str);
for(int i = 0; i < len; i++) B.num[len - i - 1] = str[i] - '0';
Minus(A, B, C); // 计算结果
print(C); // 输出
return 0;
}
char str[MAXN];
struct BigNum {
int num[MAXN], len;
}A, B, C;
void print(BigNum &x) { //输出大整数x
for(int i = x.len - 1; i >= 0; i--) printf("%d", x.num[i]);
printf("\n");
}
void Multi(BigNum &x, int y, BigNum &z) {
z.len = x.len; // 最小长度
for(int i = 0; i < z.len; i++) z.num[i] = x.num[i] * y; //逐位相乘
for(int i = 0; i < z.len; i++) { // 进位处理
z.num[i + 1] += z.num[i] / 10;
z.num[i] %= 10;
if(i == z.len - 1 && z.num[i + 1]) ++z.len; // 最高位进位
}
return ;
}
int main() {
// 读取并倒序存储大整数A
scanf("%s", str);
int len = strlen(str);
A.len = len;
for(int i = 0; i < len; i++) A.num[len - i - 1] = str[i] - '0';
int b;
scanf("%d", &b);
Multi(A, b, C); // 计算结果
print(C); // 输出
return 0;
}
#include
#define MAXN 11111
using namespace std;
char str[MAXN];
struct BigNum {
int num[MAXN], len;
}A, B, C;
void print(BigNum &x) { //输出大整数x
for(int i = x.len - 1; i >= 0; i--) printf("%d", x.num[i]);
printf("\n");
}
void Multi(BigNum &x, BigNum &y, BigNum &z) {
z.len = x.len + y.len; // 最大长度
for(int i = 0; i < x.len; i++)
for(int j = 0; j < y.len; j++) // 模拟乘法竖式
z.num[i + j] += x.num[i] * y.num[j];
for(int i = 0; i < z.len; i++) { // 进位处理
z.num[i + 1] += z.num[i] / 10;
z.num[i] %= 10;
}
while(z.len > 1 && !z.num[z.len - 1]) --z.len;
return ;
}
int main() {
// 读取并倒序存储大整数A
scanf("%s", str);
int len = strlen(str);
A.len = len;
for(int i = 0; i < len; i++) A.num[len - i - 1] = str[i] - '0';
// 读取并倒序存储大整数B
scanf("%s", str);
B.len = len = strlen(str);
for(int i = 0; i < len; i++) B.num[len - i - 1] = str[i] - '0';
Multi(A, B, C); // 计算结果
print(C); // 输出
return 0;
}
#include
#define MAXN 11111
using namespace std;
char str[MAXN];
struct BigNum {
int num[MAXN], len;
}A, B, C;
void print(BigNum &x) { //输出大整数x
for(int i = x.len - 1; i >= 0; i--) printf("%d", x.num[i]);
printf("\n");
}
void Div(BigNum &x, int y, BigNum &z) {
z.len = x.len; // 初始长度
int t = 0;
for(int i = z.len - 1; i >= 0; i--) {
t = t * 10 + x.num[i]; // 当前位数字等于上一位余数乘10再加上当前位数字
z.num[i] = t / y; // 除法
t %= y; // 更新t
}
while(z.len > 1 && !z.num[z.len - 1]) --z.len; //去除前导0
return ;
}
int main() {
// 读取并倒序存储大整数A
scanf("%s", str);
int len = strlen(str);
A.len = len;
for(int i = 0; i < len; i++) A.num[len - i - 1] = str[i] - '0';
int y;
scanf("%d", &y);
Div(A, y, C); // 计算结果
print(C); // 输出
return 0;
}
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int x1,y1,g;
g=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return g;
}
求出来的d必须满足 c%d==0,否则无解
x = ( c / d ) x 0 + k ( b / d ) x=(c/d)x_0+k(b/d) x=(c/d)x0+k(b/d)
y = ( c / d ) / y 0 − k ( a / d ) y=(c/d)/y_0-k(a/d) y=(c/d)/y0−k(a/d)
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,y,x);
y=y-(a/b)*x;
return d;
}
一般求一个x,所以所要求的是最小满足的x
int x=(c/d)*x0;
int k=b/d;
cout<<(x%k+k)%k<<endl;