您的位置:首页 > 其它

HDU 5768 Lucky7 (中国剩余定理+容斥)

2016-08-01 16:28 411 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768

给你n个同余方程组,然后给你l,r,问你l,r中有多少数%7=0且%ai != bi.

比较明显的中国剩余定理+容斥,容斥的时候每次要加上个(%7=0)这一组。

中间会爆longlong,所以在其中加上个快速乘法(类似快速幂)。因为普通的a*b是直接a个b相加,很可能会爆。但是你可以将b拆分为二进制来加a,这样又快又可以防爆。

//#pragma comment(linker, "/STACK:102400000, 102400000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair <int, int> P;
const int N = 1e5 + 5;
LL a[17] , b[17], fuck = 1e18;

LL Fmul(LL a , LL n , LL mod) { //快速乘法
LL res = 0;
while(n) {
if(n & 1) {
res = (res + a) % mod;
}
a = a * 2 % mod;
n >>= 1;
}
return res;
}

LL exgcd(LL a , LL b , LL &x , LL &y) {
LL res = a;
if(!b) {
x = 1;
y = 0;
}
else {
res = exgcd(b , a % b , x , y);
LL temp = x;
x = y;
y = temp - a / b * y;
}
return res;
}

LL CRT(LL a[] , LL m[] , LL n) {
LL M = 1 , res = 0;
for(LL i = 1 ; i <= n ; i++) {
M = M * m[i];
}
for(LL i = 1 ; i <= n ; i++) {
LL x , y , Mi = M / m[i];
exgcd(Mi , m[i] , x , y);
x = (x % m[i] + m[i]) % m[i];
res = (res + Fmul(x * a[i] % M , Mi , M) + M) % M;
}
if(res < 0)
res += M;
return res;
}

LL Get(LL n, LL x, LL y) {
if(x > n)
return 0;
else {
n -= x;
return (LL)(1 + n / y);
}
}

int main()
{
int t, n;
LL l , r , md[17], di[17];
scanf("%d", &t);
for(int ca = 1; ca <= t; ++ca) {
scanf("%d %lld %lld", &n, &l, &r);
di[1] = 7, md[1] = 0;
for(int i = 1; i <= n; ++i) {
scanf("%lld %lld", a + i, b + i);
}
LL res1 = 0, res2 = 0;
int limit = (1 << n) - 1;
for(int i = 1; i <= limit; ++i) {
int temp = i, index = 1;
LL mul = 7;
for(int j = 1 ; temp ; ++j) {
if(temp & 1) {
di[++index] = a[j];
md[index] = b[j];
mul *= a[j];
}
temp >>= 1;
}
if(index % 2) {
res1 -= Get(l - 1, CRT(md, di, index), mul);
res2 -= Get(r, CRT(md, di, index), mul);
}
else {
res1 += Get(l - 1, CRT(md, di, index), mul);
res2 += Get(r, CRT(md, di, index), mul);
}
}
printf("Case #%d: %lld\n",ca, r/7 - (l-1)/7 - (res2 - res1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: