歡迎大家來刷我的專題:https://vjudge.net/contest/177165#problem/I
這是一道數範圍很大的題,據說數據很水.
首先題目的意識也就是 一個方程有解,係數都是<=m,最後一個係數爲m,這個等於1的方程一定有解的話,也就是說這n+1個係數的gcd=1,互質,那麼解決問題的思路就有莫比烏斯反演,歐拉函數,容斥原理等等,不過這道題的話,前兩個不是很好想.
這裏簡要說一下容斥原理的思路.
容斥原理: 一共有
答案顯然就是
#include<cstdio>
#include<iostream>
#include<bitset>
#include<cstring>
#define ll long long
const int maxn = 1e3;
using namespace std;
int tot = 0;
int n,m;
struct BigInt{
const static int mod = 10;
int a[maxn], len;
BigInt(){
memset(a, 0, sizeof a);
len = 1;
}
BigInt(ll v){
memset(a, 0, sizeof a);
len = 0;
do{
a[len++] = v%mod;
v/=mod;
}while(v);
}
BigInt operator +(const BigInt &b)const{
BigInt res;
res.len = max(len, b.len);
for(int i = 0; i <= res.len; i++){
res.a[i] = 0;
}
for(int i = 0; i < res.len; i++){
res.a[i] += ((i < len)?a[i]:0) + ((i < b.len)?b.a[i]:0);
res.a[i+1] += res.a[i]/mod;
res.a[i] %= mod;
}
if(res.a[res.len] > 0) res.len++;
return res;
}
//保證a>=b
BigInt operator -(const BigInt &b)const{
BigInt res;
res.len = len;
for(int i = 0; i <= res.len; i++){
res.a[i] = 0;
}
for(int i = 0; i < res.len; i++){
res.a[i] += (a[i]-b.a[i]);
if(res.a[i]<0){
res.a[i]+=10;
res.a[i+1]--;
}
}
while(res.a[res.len-1]==0 && res.len > 1)res.len--;
return res;
}
BigInt operator *(const BigInt &b)const{
BigInt res;
for(int i = 0; i < len; i++){
int up = 0;
for(int j = 0; j < b.len; j++){
int temp = a[i]*b.a[j] + res.a[i+j] + up;
res.a[i+j] = temp%mod;
up = temp/mod;
}
if(up != 0)
res.a[i + b.len] = up;
}
res.len = len + b.len;
while(res.a[res.len - 1] == 0 && res.len > 1)res.len--;
return res;
}
void output(){
for(int i = len-1; i >= 0; i--)
printf("%d",a[i]);
}
void init(){
memset(a, 0, sizeof a);
len = 1;
}
};
BigInt power(BigInt a, int b){
BigInt ans = BigInt(1);
while(b){
if(b&1) ans = ans*a;
a = a*a;
b >>= 1;
}
return ans;
}
int p[maxn];
int main(){
while(~scanf("%d%d",&n,&m)){
int tot = 0;
int mm = m;
for(int i = 2; i <= m/i; i++){
if(m%i==0){
p[tot++] = i;
}
while(m%i==0){
m/=i;
}
}
if(m>1){
p[tot++] = m;
}
BigInt ans = power(mm, n);
ll tmp = 1;
int c = 0;
for(int i = 1; i < 1<<tot; i++){
c = 0; tmp = mm;
for(int j = 0; j < tot; j++)
if(i & (1 << j)){
c++;
tmp/=p[j];
}
BigInt it = BigInt(tmp);
if(c&1) ans = ans - power(it, n);
else ans = ans + power(it, n);
//ans.output();
//puts("");
}
ans.output();
puts("");
}
return 0;
}