BZOJ4407: 于神之怒加强版

Description

给下N,M,K.求

img

Input

输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示。

Output

如题

Sample Input

1 2
3 3

Sample Output

20

HINT

1<=N,M,K<=5000000,1<=T<=2000

Solution

首先可以推一波式子
\[ \begin{aligned} &\sum_{i=1}^{n}\sum_{j=1}^m(i,j)^k\\ &=\sum_{d=1}^nd^k\sum_{i=1}^{n}\sum_{j=1}^m[(i,j)=1]\\ &=\sum_{d=1}^nd^k\sum_{i=1}^{n}\sum_{j=1}^m\sum_{x|(i,j)}\mu(x)\\ &=\sum_{d=1}^nd^k\sum_{x=1}^n\mu(x)\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dx}\rfloor \end{aligned} \]
发现\(d^k\)是个完全积性函数,那么可以\(O(\sqrt{n}*\sqrt{n})=O(n)\)完成单次询问了

但是这样跑不过

所以继续推
\[ \begin{aligned} &设T=dx\\ &=\sum_{d=1}^nd^k\sum_{x=1}^n\mu(x)\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dx}\rfloor\\ &=\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{d|T}\mu(\frac{T}{d})d^k \end{aligned} \]
发现后面那个玩意可以\(nlogn\)筛出来,那么可以做到\(O(nlogn+T\sqrt{n})\),但是我被bzoj的土豆机卡了。。。所以要继续推。

研究一下后面那堆发现这是个狄利克雷卷积的形式,所以说这是个积性函数,但是莫比乌斯函数里面有个分数的话有点难写,于是根据狄利克雷卷积的定义改一下
\[ \begin{aligned} &设g(T)=\sum_{x|T}\mu(x)*(\frac{T}{x})^k\\ &g(i)=T^k*\sum_{x|T}\frac{\mu(x)}{x^k} \end{aligned} \]
考虑当T为质数的情况,设此时的\(T=p\)
\[ \begin{aligned} g(p) &=p^k*\sum_{x|p}\frac{\mu(x)}{x^k}\\ &=p^k*\left(\frac{\mu(1)}{1^k}+\frac{\mu(p)}{p^k}\right)\\ &=p^k*(1-\frac{1}{p^k})\\ &=p^k*\frac{p^k-1}{p^k}\\ &=p^k-1 \end{aligned} \]
因为\(g\)是一个积性函数,所以当i,j互质显然有
\[ g(i*j)=g(i)*g(j) \]
考虑\(j\)\(i\)的质因数的情况(因为在线性筛过程中\(j\)必为质数)
\[ \begin{aligned} &设i=r*j^c(k内不含质因子j)\\ &g(i*j)\\ &=g(r*j^{c+1})\\ &=g(r)*g(j^{c+1})\\ &考虑g(j^{c+1})=\sum_{x|j^{c+1}}\frac{\mu(x)}{x^k}\\ &显然只有当x=1或j时\mu(x)才为1,其他情况为0所以当j的指数大于2时,g值是相同的\\ &所以g(j^{c+1})=g(j^c)\\ &又因为r和j^{c+1}和j^c互质,所以有\\ &g(i*j)=g(r*j^{c+1})=g(r)*g(j^{c+1})=g(r)*g(j^c)=g(r*j^c)=g(i) \end{aligned} \]
综上可得,在线性筛过程中
\[ g(i*prime[j])= \begin{cases} g(i)*g(prime[j])(i与prime[j]互质)\\ g(i)(prime[j]为i的质因子) \end{cases} \]
所以我们用线性筛筛出这个函数\(g\),就可以\(O(n+T\sqrt{n})\)的效率了

这题我写了大半天...主要就卡在最后这个积性函数的推导...

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
#define N 5000050
 
ll n, m;
ll p[N], cnt, mu[N];
bool vis[N];
ll F[N], k, id[N], sum[N];
 
ll power(ll a, ll b) { ll ans = 1;
    while(b) {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans % mod;
}

void init() {
    cnt = 0;
    mu[1] = id[1] = F[1] = 1;
    for(ll i = 2; i < N; ++i) {
        if(!vis[i]) 
            id[i] = power(i, k) % mod, mu[i] = -1, p[++cnt] = i, F[i] = ((id[i] - 1) * power(id[i], mod - 2) + mod) % mod;
        for(ll j = 1; j <= cnt && 1ll * p[j] * i < N; ++j) {
            vis[i * p[j]] = 1;
            id[i * p[j]] = id[i] * id[p[j]] % mod;
            if(i % p[j] == 0) { F[i * p[j]] = F[i] % mod; break; }
            mu[i * p[j]] = -mu[i]; 
            F[i * p[j]] = F[i] * F[p[j]] % mod;
        }
    }
    for(ll i = 1; i < N; ++i) sum[i] = (sum[i - 1] + F[i] * id[i] % mod) % mod;
} 
 
ll calc(ll n, ll m) {
    ll ans = 0;
    if(n > m) swap(n, m);
    for(ll l = 1, r; l <= n; l = r + 1) {
        r = min(n / (n / l), m / (m / l));
        ans += 1ll * (n / l) % mod * (m / l) % mod * (sum[r] - sum[l - 1] + mod) % mod;
    }
    return ans % mod;
}
 
int main() {
    int T; scanf("%d%lld", &T, &k);
    init();
    while(T--) {
        scanf("%lld%lld", &n, &m);
        printf("%lld\n", (calc(n, m) + mod) % mod);
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
06-19 14:46
和女友两个人马上毕业,现在我在鹅实习995,周六日偶尔也去北京;她在北京金融007,经常忙到后半夜,周末也没啥休息机会两个人现在都不咋聊天了,一句话隔半小时甚至半天才回。&nbsp;她是个很优秀的妹子,工作也很努力,是值得学习一辈子的人。我在努力工作求转正,即便不行至少赚到了一段不错的实习经历。已经异地了半年,接下来可能还会持续是这个状态。我们都算是对方重要的人,只是感觉看上去不是很有未来的样子。希望牛友们给点的鼓励
梦旅奇缘:很难。异地首先就已经很难了,加上妹子是金融行业,忙碌高压,对情感需求很高,而且见惯纸醉金迷,你的很多优势在她那里可能就不算什么了。这种情况下,在她们那里遇到一个能及时照顾她的人,即使那人可能很多条件不如你,你也有可能被分手。 说白了,两个卷王就不太适合在一起。因为卷王最大的优势,在另一个卷王那里就不算优势了。
点赞 评论 收藏
分享
程序员牛肉:主要是因为小厂的资金本来就很吃紧,所以更喜欢有实习经历的同学。来了就能上手。 而大厂因为钱多,实习生一天三四百的就不算事。所以愿意培养你,在面试的时候也就不在乎你有没有实习(除非是同级别大厂的实习。) 按照你的简历来看,同质化太严重了。项目也很烂大街。 要么换项目,要么考研。 你现在选择工作的话,前景不是很好了。
点赞 评论 收藏
分享
06-18 16:45
门头沟学院 Java
玩脱了,吊着两家结果两家都不要鼠鼠了,我真想给自己两巴掌。
凉风落木楚山秋:当作是你把这两家公司从地球开除了就行了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务