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

题目链接: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,这样又快又可以防爆。

  1 //#pragma comment(linker, "/STACK:102400000, 102400000")
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <vector>
  8 #include <cmath>
  9 #include <ctime>
 10 #include <list>
 11 #include <set>
 12 #include <map>
 13 using namespace std;
 14 typedef long long LL;
 15 typedef pair <int, int> P;
 16 const int N = 1e5 + 5;
 17 LL a[17] , b[17], fuck = 1e18;
 18
 19 LL Fmul(LL a , LL n , LL mod) { //快速乘法
 20     LL res = 0;
 21     while(n) {
 22         if(n & 1) {
 23             res = (res + a) % mod;
 24         }
 25         a = a * 2 % mod;
 26         n >>= 1;
 27     }
 28     return res;
 29 }
 30
 31 LL exgcd(LL a , LL b , LL &x , LL &y) {
 32     LL res = a;
 33     if(!b) {
 34         x = 1;
 35         y = 0;
 36     }
 37     else {
 38         res = exgcd(b , a % b , x , y);
 39         LL temp = x;
 40         x = y;
 41         y = temp - a / b * y;
 42     }
 43     return res;
 44 }
 45
 46 LL CRT(LL a[] , LL m[] , LL n) {
 47     LL M = 1 , res = 0;
 48     for(LL i = 1 ; i <= n ; i++) {
 49         M = M * m[i];
 50     }
 51     for(LL i = 1 ; i <= n ; i++) {
 52         LL x , y , Mi = M / m[i];
 53         exgcd(Mi , m[i] , x , y);
 54         x = (x % m[i] + m[i]) % m[i];
 55         res = (res + Fmul(x * a[i] % M , Mi , M) + M) % M;
 56     }
 57     if(res < 0)
 58         res += M;
 59     return res;
 60 }
 61
 62 LL Get(LL n, LL x, LL y) {
 63     if(x > n)
 64         return 0;
 65     else {
 66         n -= x;
 67         return (LL)(1 + n / y);
 68     }
 69 }
 70
 71 int main()
 72 {
 73     int t, n;
 74     LL l , r , md[17], di[17];
 75     scanf("%d", &t);
 76     for(int ca = 1; ca <= t; ++ca) {
 77         scanf("%d %lld %lld", &n, &l, &r);
 78         di[1] = 7, md[1] = 0;
 79         for(int i = 1; i <= n; ++i) {
 80             scanf("%lld %lld", a + i, b + i);
 81         }
 82         LL res1 = 0, res2 = 0;
 83         int limit = (1 << n) - 1;
 84         for(int i = 1; i <= limit; ++i) {
 85             int temp = i, index = 1;
 86             LL mul = 7;
 87             for(int j = 1 ; temp ; ++j) {
 88                 if(temp & 1) {
 89                     di[++index] = a[j];
 90                     md[index] = b[j];
 91                     mul *= a[j];
 92                 }
 93                 temp >>= 1;
 94             }
 95             if(index % 2) {
 96                 res1 -= Get(l - 1, CRT(md, di, index), mul);
 97                 res2 -= Get(r, CRT(md, di, index), mul);
 98             }
 99             else {
100                 res1 += Get(l - 1, CRT(md, di, index), mul);
101                 res2 += Get(r, CRT(md, di, index), mul);
102             }
103         }
104         printf("Case #%d: %lld\n",ca, r/7 - (l-1)/7 - (res2 - res1));
105     }
106     return 0;
107 }
时间: 2024-10-08 21:56:17

HDU 5768 Lucky7 (中国剩余定理+容斥)的相关文章

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768: 题目分析: 因为满足任意一组pi和ai,即可使一个"幸运数"被"污染",我们可以想到通过容斥来处理这个问题.当我们选定了一系列pi和ai后,题意转化为求[x,y]中被7整除余0,且被这一系列pi除余ai的数的个数,可以看成若干个同余方程联立成的一次同余方程组.然后我们就可以很自然而然的想到了中国剩余定理.需要注意的是,在处理中国剩余定理的过程中,可能会发生超出L

hdu_5768_Lucky7(中国剩余定理+容斥)

题目链接:hdu_5768_Lucky7 题意: 给你一个区间,问你这个区间内是7的倍数,并且满足%a[i]不等于w[i]的数的个数 乍一看以为是数位DP,仔细看看条件,发现要用中国剩余定理,然后容斥一下就出答案了,不过这里在中国剩余定理里面的乘法会有数据爆long long ,所有要写一个高精度乘法,这里卡死很多人. 1 #include <bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 using namespace

HDU5768Lucky7(中国剩余定理+容斥定理)(区间个数统计)

When ?? was born, seven crows flew in and stopped beside him. In its childhood, ?? had been unfortunately fall into the sea. While it was dying, seven dolphins arched its body and sent it back to the shore. It is said that ?? used to surrounded by 7

【中国剩余定理】【容斥原理】【快速乘法】【数论】HDU 5768 Lucky7

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5768 题目大意: T组数据,求L~R中满足:1.是7的倍数,2.对n个素数有 %pi!=ai  的数的个数. 题目思路: [中国剩余定理][容斥原理][快速乘法][数论] 因为都是素数所以两两互素,满足中国剩余定理的条件. 把7加到素数中,a=0,这样就变成解n+1个同余方程的通解(最小解).之后算L~R中有多少解. 但是由于中国剩余定理的条件是同时成立的,而题目是或的关系,所以要用容斥原理叠加删

HDU 5768 Lucky7 (容斥原理 + 中国剩余定理 + 状态压缩 + 带膜乘法)

题意:……应该不用我说了,看起来就很容斥原理,很中国剩余定理…… 方法:因为题目中的n最大是15,使用状态压缩可以将所有的组合都举出来,然后再拆开成数组,进行中国剩余定理的运算,中国剩余定理能够求出同时满足余膜条件的最小整数x,x在(1,M)之间由唯一值,M是各个除数的乘积,所有符合条件的解为ans = x+k*M,可以知道在[1,R]这个区间内,有(M+R-x)/ M个k符合条件,然后在运算中为了防止溢出,所以使用了带膜乘法,就是将乘数转化为二进制,通过位移运算符,在中间过程中不断的取膜(看代

HDU 5768 Lucky7(CRT+容斥原理)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5768 [题目大意] 求出一个区间内7的倍数中,对于每个ai取模不等于bi的数的个数. [题解] 首先,对于x mod 7=0,和选取的一些x mod ai=bi,我们可以利用CRT解出最小的x值,那么这样子我们就可以对所有的aibi选取方式做容斥,得到x mod 7=0成立且所有x mod ai=bi不成立的x的个数.也就是答案. [代码] #include <cstdio> #include

HDU 6053 TrickGCD 莫比乌斯函数/容斥/筛法

题意:给出n个数$a[i]$,每个数可以变成不大于它的数,现问所有数的gcd大于1的方案数.其中$(n,a[i]<=1e5)$ 思路:鉴于a[i]不大,可以想到枚举gcd的值.考虑一个$gcd(a_1,a_2,a_3…a_n)=d$,显然每个$a_i$的倍数都满足,有$\frac{a_i}{d}$种方案 那么一个d对答案的贡献为\[\prod_{i=1}^{min(a)}{\lfloor\frac{a_i}{d}\rfloor}    \] 但是所有的d计入会有重复情况,考虑容斥,对d进行素数分

hdu 6390 欧拉函数+容斥(莫比乌斯函数) GuGuFishtion

http://acm.hdu.edu.cn/showproblem.php?pid=6390 题意:求一个式子 题解:看题解,写代码 第一行就看不出来,后面的sigma公式也不会化简.mobius也不会 就自己写了个容斥搞一下(才能维持现在的生活) //别人的题解https://blog.csdn.net/luyehao1/article/details/81672837 #include <iostream> #include <cstdio> #include <cstr

HDU 5768 - Lucky7

题意: 给出x, y, m[1...n], a[1..n].     在[x,y]中寻找 p % 7 = 0 且对任意(1<= i <=n) p % m[i] != a[i] 的数字的个数    分析: 可用容斥定理,先在[x,y]找出所有7的倍数,再根据多个模线性方程连立,去掉所有不合法的    因 m[1...n] 互质,故可直接使用中国剩余定理. 并且需要在其中用 快速加法 防止超 long long 1 #include <iostream> 2 #include <