# GuGuFishtion (hdu 6390 莫比乌斯反演)

$\frac{\phi \left(\left(ab\right)}{\phi \left(a\right)\phi \left(b\right)}=\frac{gcd\left(a,b\right)}{\phi \left(gcd\left(a,b\right)\right)}$

#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
int MOD=1e9+7;
bool vis[maxn];
int phi[maxn];
int mu[maxn];
int Smu[maxn];
int inv[maxn]={1,1};
int T,N,M;
vector<int>prime;
void PHI(int n)
{
memset(vis,1,sizeof(vis));
phi[1]=1;
mu[1]=1;
Smu[1]=1;
for(int i=2;i<=n;i++)
{
if(vis[i])
{
prime.push_back(i);
phi[i]=i-1;
mu[i]=-1;
}
for(int j=0;j<prime.size()&&i*prime[j]<=n;j++)
{
vis[i*prime[j]]=0;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
mu[i*prime[j]]=0;
break;
}
else
{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
mu[i*prime[j]]=-mu[i];
}
}
Smu[i]=Smu[i-1]+mu[i];
}
}
LL F(int n)//求gcd=n的倍数的个数
{
return (LL)(N/n)*(M/n);
}
LL f(int n)求gcd=n的个数
{
LL res=0;
for(int i=1,j,d=n;d<=N;i=j+1)
{

j=min(N/(N/i),(M/(M/i)));
res+=(LL)(Smu[j]-Smu[i-1])*F(d);
if(res>MOD)res%=MOD;
d+=(j-i+1)*n;

}
return res;
}
LL ksm(LL a,LL b,LL mod)
{
LL res=1,base=a;
while(b)
{
if(b&1)res=(res*base)%mod;
base=(base*base)%mod;
b>>=1;
}
return res;
}
int main()
{
PHI(1e6);

cin>>T;
while(T--)
{
cin>>N>>M>>MOD;
if(N>M)swap(N,M);
LL res=0;
for(int i=1;i<=N;i++)
{
if(i>1)inv[i]=(LL)(MOD-MOD/i)*inv[MOD%i]%MOD;
res+=(LL)f(i)*i%MOD*inv[phi[i]]%MOD;
if(res>MOD)res%=MOD;
}
cout<<res<<endl;
}
}

#Sequence（hdu 6395 分段矩阵快速幂）



# include”bits/stdc++.h”

using namespace std;
typedef long long LL;
const int MOD=1e9+7;
struct Matrix
{
int n;
LL a[3][3];
Matrix (int n):n(n)
{
for(int i=0;i


#Swordsman（hdu 6396）

~~原来以前的 getchar 那种挂是假的挂啊，，，我才知道~~

`

# define C(n,m) ((long long)fac[(n)]*inv[(m)]%MOD*inv[(n)-(m)]%MOD)

using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;

//优秀的输入挂
namespace fastIO {
#define BUF_SIZE 100000
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ’ ’ || ch == ‘\n’ || ch == ‘\r’ || ch == ‘\t’;
}
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - ‘0’; (ch = nc()) >= ‘0’ && ch <= ‘9’; x = x * 10 + ch - ‘0’);
}
#undef BUF_SIZE
};
//using namespace fastIO;

int N,K;
struct AAA
{
int v,id;
bool operator<(const AAA &t)const
{
return v