【中国剩余定理】【容斥原理】【快速乘法】【数论】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中有多少解。

  但是由于中国剩余定理的条件是同时成立的,而题目是或的关系,所以要用容斥原理叠加删减。

  中间过程中可能会爆long long,所以要用快速乘法(和快速幂类似,只是乘改成加)

  1 //
  2 //by coolxxx
  3 //
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<memory.h>
  9 #include<time.h>
 10 #include<stdio.h>
 11 #include<stdlib.h>
 12 #include<string.h>
 13 //#include<stdbool.h>
 14 #include<math.h>
 15 #define min(a,b) ((a)<(b)?(a):(b))
 16 #define max(a,b) ((a)>(b)?(a):(b))
 17 #define abs(a) ((a)>0?(a):(-(a)))
 18 #define lowbit(a) (a&(-a))
 19 #define sqr(a) ((a)*(a))
 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 21 #define eps (1e-8)
 22 #define J 10000000
 23 #define MAX 0x7f7f7f7f
 24 #define PI 3.1415926535897
 25 #define N 24
 26 using namespace std;
 27 typedef long long LL;
 28 int cas,cass;
 29 int n,m,lll;
 30 LL l,r,ans;
 31 LL p[N],a[N];
 32 bool u[N];
 33 LL cheng(LL a,LL b,LL mod)
 34 {
 35     LL sum=0;
 36     for(;b;b>>=1)
 37     {
 38         if(b&1LL)sum=(sum+a)%mod;
 39         a=(a+a)%mod;
 40     }
 41     return sum;
 42 }
 43 LL exgcd(LL a,LL b,LL &x,LL &y)
 44 {
 45     if(!b){x=1,y=0;return a;}
 46     LL d=exgcd(b,a%b,y,x);
 47     y-=a/b*x;
 48     return d;
 49 }
 50 LL china(int nn)
 51 {
 52     LL sum=0,tot=1,tott,x,y;
 53     int i;
 54     for(i=1;i<=nn;i++)if(u[i])tot*=p[i];
 55     for(i=1;i<=nn;i++)
 56     {
 57         if(!u[i])continue;
 58         tott=tot/p[i];
 59         exgcd(tott,p[i],x,y);
 60         x=(x%p[i]+p[i])%p[i];
 61         sum=((sum+cheng(a[i]*tott%tot,x,tot))%tot+tot)%tot;
 62     }
 63     sum=(r+tot-sum)/tot-(l-1+tot-sum)/tot;
 64     return sum;
 65 }
 66 int main()
 67 {
 68     #ifndef ONLINE_JUDGE
 69 //    freopen("1.txt","r",stdin);
 70 //    freopen("2.txt","w",stdout);
 71     #endif
 72     int i,j,k,ii;
 73 //    for(scanf("%d",&cas);cas;cas--)
 74     for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 75 //    while(~scanf("%s",s))
 76 //    while(~scanf("%d",&n))
 77     {
 78         ans=0;
 79         printf("Case #%d: ",cass);
 80         scanf("%d%lld%lld",&n,&l,&r);
 81         for(i=1;i<=n;i++)
 82             scanf("%lld%lld",&p[i],&a[i]);
 83         lll=1<<n;
 84         n++;
 85         u[n]=1;p[n]=7;a[n]=0;
 86         for(i=0;i<lll;i++)
 87         {
 88             for(j=i,k=0,ii=1;ii<n;j>>=1,ii++)
 89             {
 90                 u[ii]=j&1;
 91                 k+=u[ii];
 92             }
 93             k=k&1?-1:1;
 94             ans+=1LL*k*china(n);
 95         }
 96         printf("%lld\n",ans);
 97     }
 98     return 0;
 99 }
100 /*
101 //
102
103 //
104 */

时间: 2024-12-15 04:34:26

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

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

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

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

http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Problem Description 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

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, "/S

中国剩余定理模板&amp;俄罗斯乘法

void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){ if(!b){d=a;x=1LL;y=0LL;} else {ex_gcd(b,a%b,d,y,x);y-=x*(a/b);} }/////大数乘法取模转换成加法取模,避免爆long long ll mult(ll a,ll k,ll m){ ll res=0; while(k){ if(k&1LL)res=(res+a)%m; k>>=1; a=(a<<1)%m;

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 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 <

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

HDU 5768Lucky7(多校第四场)容斥+中国剩余定理(扩展欧几里德求逆元的)+快速乘法

地址:http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 754    Accepted Submission(s): 279 Problem Description When ?? was born, seven crows flew

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

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