hdu - 4790 - Just Random(容斥 + 组合数学)

题意:在 [a, b] 取一个整数 x,在 [c, d] 取一个整数 y,求满足 (x + y) % p = m 的 (x, y) 的对数(0 <= a <= b <= 10 ^ 9, 0 <=c <= d <= 10 ^ 9, 0 <= m < p <= 10 ^ 9)。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4790

——>>2013年成都区赛最后一题,当时TLE6次无果。。。。加上 B 的无限WA,铁铁地铁了。。

。。。。。。。

设 F(a, b) 表示 [0, a] 取 x,[0, b] 取 y 的满足条件的 (x, y) 对数,则:

结果 = F(b, d) - F(a - 1, d) - F(c - 1, b) + F(a - 1, c - 1)

怎么求 F 呢?

因为 (x + y) % p,所以,可以 (x % p + y % p) % p

[0, a] 各点依次 % p 后的序列是:0, 1, 2, ..., p - 1,  0, 1, 2, ..., p - 1,0, 1, 2, ...(共 (a + 1) / p 个完整周期)

[0, b] 各点依次 % p 后的序列是:0, 1, 2, ..., p - 1,  0, 1, 2, ..., p - 1, 0, 1, 2, ...(共 (b + 1) / p 个完整周期)

[0, a] 上的一个完整周期,和 [0, b] 上的一个完整周期组合,可以得到 p 个 (x, y) 满足条件(前者取一个数x, 后者一定可以找到一个相应的 y,使得(x + y) % p = m,这时将x, y同比例一个增大一个减小,得到的 (x + k, y - k) 也满足条件。。共有 p 个)。。

所以,[0, a] 的完整区间与 [0, b] 的完整区间组合,可得到 ((a + 1) / p) *((b
+ 1) / p)* p 个 (x, y)
满足条件(蓝色这层括号不可少!!)。。

设 ar = (a + 1) % p

设 br = (b + 1) % p

[0, a] 最后剩下的不完整片段为 0, 1, 2, ..., ar - 1

[0, b] 最后剩下的不完整片段为 0, 1, 2, ..., br - 1

[0, a] 的剩余区间 [0, ar - 1],与 [0, b] 的一个完整区间 [0, p - 1] 组合,可得到 ar 个满足要求的 (x, y) 。。

[0, b] 的剩余区间 [0, br - 1],与 [0, a] 的一个完整区间 [0, p - 1] 组合,可得到 br 个满足要求的 (x, y) 。。

[0, a] 的剩余区间 [0, ar - 1],与 [0, b] 的所有完整区间 [0, p - 1] 组合,可得到 ar *((b + 1) / p)个满足要求的 (x, y) 。。

[0, b] 的剩余区间 [0, br - 1],与 [0, a] 的所有完整区间 [0, p - 1] 组合,可得到
br * ((a + 1) / p)个满足要求的 (x, y) 。。

最后,考虑 [0, a] 的剩余区间与[0, b]的剩余区间组合。。

先来一次--ar, --br,方便后面处理。。

如果在 [0, br] 上取0,[0, ar] 上就必须取 m,但是 m 能不能取到呢?不一定,要对 m 进行分类讨论。。

当 ar > m 时,对于区间 [0, ar](别用 >= 放到这里来哦:原因请测试 0 0 0 0 10 0 这组样例):

这样移动:0 <-- m,[0, br] 上这样移动:0 --> xx,此时可得到 min(m + 1, br + 1)个满足要求的 (x, y)。。

这样移动:<-- ar,要使 (ar + y ) % p = m,则最小的 miny = (m - ar + p) % p,如果 miny <= br,则可得到 br - miny + 1 个满足要求的 (x, y)。。(这个地方要想通哦,为什么ar往左的时候不用固定边界?当 y 到达右边界 br,而 x 未到 m 时,说明 (m, x) 之间的数需要 y 取小于0
的数或者大于 br 的数才可以,这是不可能的;当 x 越过了 m 时,说明 [x, m] 之间的数既可以取两个不同的位置,并不是重复)

当 ar < m 时,对于区间 [0, ar]:

即使 [0, br] 上取 y = 0 时不可行的。。

要使 (ar + y ) % p = m,则最小的 miny = (m - ar + p) % p,如果 miny <= br,则可得到 min(ar + 1, br - miny + 1) 个满足要求的 (x, y)。。

当 ar == m 时,可得 min(ar + 1, br + 1) 个满足要求的(x, y)。。

于是可求得 F ,继续求得最终的结果。。

#include <cstdio>
#include <algorithm>

using std::min;

typedef long long ll;

ll F(ll a, ll b, ll p, ll m)
{
    if (a < 0 || b < 0) return 0;

    ll ret = 0;

    ret =  ((a + 1) / p) * ((b + 1) / p) * p;
    ll ar = (a + 1) % p;
    ll br = (b + 1) % p;
    if (!ar && !br) return ret;

    if (ar)
    {
        ret += ar * ((b + 1) / p);
    }
    if (br)
    {
        ret += br * ((a + 1) / p);
    }
    if (!ar || !br) return ret;

    --ar;
    --br;
    ll miny = (m - ar + p) % p;
    if (ar > m)
    {
        ret += min(m + 1, br + 1);
        if (miny <= br)
        {
            ret += br - miny + 1;
        }
    }
    else if (ar < m)
    {
        if (miny <= br)
        {
            ret += min(ar + 1, br - miny + 1);
        }
    }
    else
    {
        ret += min(ar + 1, br + 1);
    }

    return ret;
}

ll Gcd(ll a, ll b)
{
    return b == 0 ? a : Gcd(b, a % b);
}

int main()
{
    int T, kase = 0;
    ll a, b, c, d, p, m;

    scanf("%d", &T);
    while (T--)
    {
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &d, &p, &m);
        ll A = F(b, d, p, m) - F(a - 1, d, p, m) - F(c - 1, b, p, m) + F(a - 1, c - 1, p, m);
        ll B = (b - a + 1) * (d - c + 1);
        ll gcd = Gcd(A, B);
        printf("Case #%d: %I64d/%I64d\n", ++kase, A / gcd, B / gcd);
    }

    return 0;
}
时间: 2024-09-29 06:55:33

hdu - 4790 - Just Random(容斥 + 组合数学)的相关文章

HDU 4790 Just Random 【构造】

题目链接:传送门 题目大意:给你a, b, c, d, p and m(0 <= a <= b <= 109, 0 <=c <= d <= 109, 0 <= m < p <= 109).让你从 [a, b] 中取出一个x,从[c, d] 中取出一个y,使得(x+y)(mod p)=m,求一共有多少种可能. 看见题目就想到了用构造的想法,讲解构造成二维坐标系,x+y=k*p+m是一条线,求这条线与构造的矩形(由点组成)一共有几个交点,这个矩阵也是有一定

hdu 4790 Just Random 神奇的容斥原理

1 /** 2 大意: 给定[a,b],[c,d] 在这两个区间内分别取一个x,y 使得 (x+y)%p = m 3 思路:res = f(b,d) -f(b,c-1)-f(a-1,d)+f(a-1,c-1); f(b,d ) 表示在[0,b],[0,d] 之间有多少个符合上述要求的数 4 1.将[0,b] 分为两部分, b/p 和 b%p 能整除p的[0,(b/p)*p] 和[(b/p)*p+1,b ] 同理[0,d]也可以这样分, 这样对于[0,b] [0,d ] 分别有两种情况,则一共有四

HDU - 4790 Just Random

题意:求从[a,b],[c,d]两个区间找到两个数使得他们的和%p=m,求概率 思路:我们想办法把区间的左范围化到0,那么结果就相对好弄了,应用容斥原理比直接解答问题简单点,假设f(a,b)是区间[0,a],[0,b]中满足条件的个数,设p=6.m=2 那么第一个区间可以看成 : A=[0,1,2,3,4,5]+[0,1,2,3,4,5]+..... B= (0,1,2,3,4) 第二个区间可以看成:C=[0,1,2,3,4,5]+....D=(0,1) 那么题目就可以看成:A+C,A+D, B

HDU 5321 Beautiful Set 容斥 (看题解)

HDU 5321 感觉有点抗拒这种题目, 看到就感觉自己不会写,其实就是个沙雕题, 感觉得找个时间练练这种题. g[ i ] 表示gcd为 i 的倍数的方案数, f[ i ] 表示gcd为 i 的方案数, 然后先算g[ i ]然后直接容斥. #pragma GCC optimize(2) #pragma GCC optimize(3) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull

HDU 4135 Co-prime(容斥+数论)

Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5526    Accepted Submission(s): 2209 Problem Description Given a number N, you are asked to count the number of integers between A and B

HDU 5297 Y sequence 容斥/迭代

Y sequence Problem Description Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hates those numbers which can be written as a^b (a, b are positive integers,2<=b<=r),so he removed them all.Yellowstar ca

HDU 3970 Harmonious Set 容斥欧拉函数

链接 题解:www.cygmasot.com/index.php/2015/08/17/hdu_3970 给定n 求连续整数[0,n), 中任意选一些数使得选出的数和为n的倍数的方法数 ...并不会如何递推.. 思路: 然后这是公式:点击打开链接 a(n) = 1/n * sum_{d divides n and d is odd} 2^(n/d) * phi(d). d最大是n,也就是1e9,要计算1e9的phi,所以容斥来算phi. #pragma comment(linker, "/STA

HDU 4135 Co-prime(组合+容斥)

Problem Description Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N. Two integers are said to be co-prime or relatively prime if they have no common positive divisors other tha

HDU 4609 3-idiots FFT+容斥

一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完全可以母函数,无奈数据很大,就用FFT了 然后难点在于最后的统计,要减去自身,两个都大的,一大一小,包含自身,这是用到了容斥,再做相似的题的时候,应该多看看这方面 注:再次高度仰慕kuangbin神,这是我FFT的第二题,也是第二次用kuangbin FFT模板 #include <stdio.h>

HDU 1695 GCD(容斥定理)

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7529    Accepted Submission(s): 2773 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y