Welcome to Liukejie|

liukejie

园龄:1年8个月粉丝:5关注:11

题解:P9788 [ROIR 2020 Day2] 区域规划

思路 1

观察式子,不妨设 a=c+t,b=d+w,那么有 (c+t)(d+w)cd=n,即 cw+td+tw=n,考虑枚举 t,w,注意到 c,d,t,w>0,所以 tw<n,所以 wnt, 那么问题转化成 cw+td=ntw 的正整数解,其中 t,w,n 已知,故可使用 exgcd,时间复杂度为 O(nlog2n)

但还要注意 axbx,所以答案要减去 a=xb=x 的情况。

考虑容斥,答案即为 a=x 时的答案加上 b=x 时的答案减去 a=xb=x 的答案,后者整除分块容易解决,考虑前者(这里只考虑 a=x 的情况,b=x 同理),注意到 bn,考虑枚举 c,那么转化成求 xbcd=n 的正整数解,其中x,c,n 已知,可以使用 exgcd,时间复杂度为 O(nlogn)

综上所述,时间复杂度为 O(nlog2n)

思路 2

当然是暴力加优化了。

我们固定 a,bc。然后我们可以发现 d 是由方程 abcd=n 的唯一确定的:如果 abnc 的倍数,那么 d=(abn)÷c,否则没有合适的 d。注意记得要检查 b>d

综上所述,时间复杂度 O(n3)

思路 2 代码如下

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = l; i <= r; ++ i)
#define per(i, r, l) for(int i = r; i >= l; -- i)
int n, x, ans;
main()
{
    cin >> n >> x;
    for(int i = 1; i <= n + 1;++ i)
    {
        if(i == x) continue;
        rep(j, i, n + 1)
        {
            if(j == x || i * j <= n) continue;
            rep(k, max(1, (i * j - n) / j), i - 1)
            {
                if((i * j - n) / k >= j) continue;
                if((i * j - n) % k == 0) ans += 1 + (i != j);
            }
        }
    }
	printf("%d", ans);
    return 0;
}
posted @   liukejie  阅读(3)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起