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

  题意:……应该不用我说了,看起来就很容斥原理,中国剩余定理……

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

  注意:为了简化运算,把(7,0)这一组加进去,带膜乘法中,需要使用同余膜定理把乘数转化为整数,因为欧几里德算法有可能返回负数,不转化会陷入死循环,我之前忘了,结果……题目给的样例都已经死在了里面……

  感悟:真不愧是多校训练赛,一个题目融合了这么多知识点。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 20
#define LL long long
int n,cnt;
LL X,Y,p[N],a[N],Pt[N],At[N];
int Get_Zuhe(int k){
    int ip;
    cnt = ip = 0;
    while(k){
        if(k&1){
            Pt[cnt] = p[ip];
            At[cnt] = a[ip];
            cnt++;
        }
        ip++;
        k >>= 1;
    }
    Pt[cnt] = 7;
    At[cnt] = 0;
    cnt++;
    return (cnt%2);
}
LL ex_gcd(LL a,LL b,LL &x,LL &y){
    if(b==0) {
        x=1; y=0;
        return a;
    }
    LL R = ex_gcd(b,a%b,y,x);
    y -= x*(a/b);
    return R;
}
LL Mul(LL x,LL y,LL M){
    LL ans = 0;
    while(y){
        //cout<<y<<endl;
        if(y&1) ans = (ans+x%M)%M;
        x = (x + x) % M;
        y >>= 1;
    }
    return ans;
}
LL China(){
    LL M = 1,m,ret = 0,x,y,L,R;
    for(int i = 0;i < cnt;i++) M *= Pt[i];
    for(int i = 0;i < cnt;i++){
        m = M/Pt[i];
        ex_gcd(m,Pt[i],x,y);
        x = (x+M)%M;///不要忘记转化为正数
        ret = (ret+Mul(Mul(m,x,M),At[i],M)%M) % M;
    }
    ret = (ret+M)%M;
   // printf("M = %I64d\n",M);
  //  printf("ret = %I64d\n",ret);
    R = (Y+M-ret)/M;
    L = (X-1+M-ret)/M;
    return R - L;
}
LL Solve(){
    int tmp = (1<<n),judge;
    LL all = Y/7 - (X-1)/7;
    LL sum = 0,ch;
    for(int i = 1;i < tmp;i++){
        judge = Get_Zuhe(i);
        ch = China();
     //   printf("china[%d] = %I64d\n",i,ch);
        if(judge) sum -= ch;
        else sum += ch;
    }
    return (all - sum);
}
int main(){
   // freopen("A.in.cpp","r",stdin);
    int t,ca = 0;
    scanf("%d",&t);
    while(t--){
        scanf("%d %I64d %I64d",&n,&X,&Y);
        for(int i = 0;i < n;i++){
            scanf("%I64d %I64d",&p[i],&a[i]);
        }
        printf("Case #%d: %I64d\n",++ca,Solve());
    }
    return 0;
}
时间: 2024-10-11 22:23:35

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

HDU 4640 Island and study-sister(状态压缩)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640 题意:给出一个无向图,边有权值.三个人初始时呆在1号点.在其余n-1个点中有些点要求被遍历到.且除了1号点之外每个点最多只能被一个人遍历.求要求被遍历的点中最后被遍历的点的最小时刻. 思路:用f[st][i]表示一个人遍历完集合st最后停在i的最小时间,之后用f[st][i]得到f1[st],表示遍历完集合st的最小时间.然后得到dp[i][st]表示i个人遍历完st的最小时间. int g[

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

[ACM] HDU 1400 Mondriaan&#39;s Dream (状态压缩,长2宽1长方形铺满)

Mondriaan's Dream Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 783    Accepted Submission(s): 506 Problem Description Squares and rectangles fascinated the famous Dutch painter Piet Mondri

HDU 3579 Hello Kiki 中国剩余定理(合并方程

题意: 给定方程 res % 14 = 5 res % 57 = 56 求res 中国剩余定理裸题 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> using namespace s

hdu 3579 Hello Kiki (中国剩余定理)

Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1943    Accepted Submission(s): 693 Problem Description One day I was shopping in the supermarket. There was a cashier counting coins s

【中国剩余定理】【容斥原理】【快速乘法】【数论】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(中国剩余定理 + 容斥原理)

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

HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由于得到每张卡片的状态不知道,所以用状态压缩,dp[i] 表示这个状态时,要全部收齐卡片的期望. 由于有可能是什么也没有,所以我们要特殊判断一下.然后就和剩下的就简单了. 另一个方法就是状态压缩+容斥,同样每个状态表示收集的状态,由于每张卡都是独立,所以,每个卡片的期望就是1.0/p,然后要做的就是要去重,既然