GuGuFishtion (hdu 6390 莫比乌斯反演)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6390 
 
关于这个公式的化简。。。 看这个
其实就是求:
所有的 的时候的
所有的 的时候的
所有的 的时候的
所有的 的时候的
而求 的个数不就是很经典的莫比乌斯的题么,我这里就是 表示 的个数, 表示 的倍数的个数
#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 分段矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6395
比赛完之后再看这道题,其实也没有什么。。。
这道题最关键的就是怎么快速的分段
其实这也是非常常见的手法,在莫比乌斯反演的裸题以及杜教筛什么的都有:
就是在 $[i,\frac{x}{x/i}]$这段区间内,$\frac{x}{i}$的值是一样的,而且只有 $sqrt(x)个值$
  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)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6396
题意:就是说有 $n$ 个怪,最多有 $5$ 种属性,自己也有$5$ 种属性,要在自己的每种属性都大于怪的每种属性的时候,就阔以把怪杀死,并且自己的属性还会得到对应的提升
问:最多能杀多少怪,以及最后自己的每个属性的值是多少?
参考博客:昨天看的今天写的。。。然后就没找到这位童鞋的博客T_T
这道题我参考的这位童鞋的思路感觉非常好懂:
就是先把每个属性从小到大排序,把比自己小的属性先记录下来,用一个 $sum[i]$ 表示第 $i$ 个怪物记录了多少属性,然后在看如果某个怪物的 $sum$ 达到了 $K$ 个,那么就把这个怪物吃了就行了
然后这道题还非要输入挂,于是又从那位童鞋那里得到了一个优秀的输入挂
~~原来以前的 getchar 那种挂是假的挂啊,,,我才知道~~
  include”bits/stdc++.h”
define out(x) cout<<#x<<”=”<
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 
 //fread -> read 
 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’; 
 } 
 inline void read(int &x) { 
 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

京公网安备 11010502036488号