标签:style blog http io color ar sp on 2014
题意:在 [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; }
hdu - 4790 - Just Random(容斥 + 组合数学)
标签:style blog http io color ar sp on 2014
原文地址:http://blog.csdn.net/scnu_jiechao/article/details/40818903