HDU 5768 Lucky7 中国剩余定理

来源:互联网 发布:美国eia数据 编辑:程序博客网 时间:2024/06/07 01:45

转载声明:http://blog.csdn.net/acdreamers/article/details/8050018 (模板)

题意:给你一段区间的,要求能被7整除的个数,然后给你n个条件, 其中的得到所有数不能满足 给出的 x%x1=r1, x%x2=r2。。。等条件.输出个数.

个人感想:
这是一道中国剩余定理题目, 我当时比赛的时候我也不会做..我只是知道有这样的公式..就是可以求出满足的所有解,但我不知道是什么鬼..然后大牛告诉我了是中国剩余定理.我特么就半桶水的东西,我感觉怎么也不会考…然后之前都没学下去,真是瞎鸡巴搞了. 我是知道要用到容斥,算了..不说心酸史, 我直接套上链接的模板去做的,在统计区间中整数的数组的时候要注意 最左区间要-1, 和求那个前缀和一样,否则就除问题了,我坑了一个多小时在那.默哀.. 例如 求 7<= 7t<=9;满足的条件中 t的个数, 这时候答案是0的! 因为是向下取整导致这样的问题,所以求t时 应该 7-1<7t<=9 这样才求出来是1! 而且要注意 t能满足0的情况,这样的区间相减是不包括0的!!

/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * *///#define OUT#include <iostream>using namespace std;#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <sstream>#include <cctype>#include <vector>#include <set>#include <cstdlib>#include <map>#include <queue>//#include<initializer_list>//#include <windows.h>//#include <fstream>//#include <conio.h>#define MaxN 0x7fffffff#define MinN -0x7fffffff#define Clear(x) memset(x,0,sizeof(x))const int INF=0x3f3f3f3f;typedef long long LL;const int maxn=20;LL n,x,y;int T;LL a[maxn],p[maxn];LL gcd(LL a,LL b){    return b? gcd(b, a % b) : a;}void extend_Euclid(LL a, LL b, LL &x, LL &y){    if(b == 0)    {        x = 1;        y = 0;        return;    }    extend_Euclid(b, a % b, x, y);    LL tmp = x;    x = y;    y = tmp - (a / b) * y;}LL Inv(LL a, LL b){    LL d = gcd(a, b);    if(d != 1) return -1;    LL x, y;    extend_Euclid(a, b, x, y);    return (x % b + b) % b;}bool Merge(LL a1, LL m1, LL a2, LL m2, LL &a3, LL &m3){    LL d = gcd(m1, m2);    LL c = a2 - a1;    if(c % d) return false;    c = (c % m2 + m2) % m2;    m1 /= d;    m2 /= d;    c /= d;    c *= Inv(m1, m2);    c %= m2;    c *= m1 * d;    c += a1;    m3 = m1 * m2 * d;    a3 = (c % m3 + m3) % m3;    return true;}LL solve(int n){    LL a1 = 0;    LL m1 = 7;    int tmp=0;    while(n)    {        if(n&1)        {            LL a2 = a[tmp];            LL m2 = p[tmp];            LL m3, a3;            if(!Merge(a1, m1, a2, m2, a3, m3))                return -1;            a1 = a3;            m1 = m3;        }        tmp++;        n>>=1;    }    a1=(a1 % m1 + m1) % m1;    LL res=0;    res+=((y-a1)/m1 -(x-a1-1)/m1);    if(a1>=x&&a1<=y)res++;//至于为什么要特殊判断 主要我们求出来的时候是( x<=a1+mt<=y,那么两边互相消去之后的t的个数是不包括0的,所以要特判一下.    return res;}LL getT(int n){    int res=0;    while(n)    {        if(n&1)res++;        n>>=1;    }    return res;}LL f(LL x){    if(x%2)return 1;    return -1;}int main(){#ifdef OUT    freopen("coco.txt","r",stdin);    freopen("lala.txt","w",stdout);#endif    scanf("%d",&T);    for(int cas=1; cas<=T; cas++)    {        scanf("%I64d%I64d%I64d",&n,&x,&y);        LL ans=(y/7-(x-1)/7);        for(int i=0; i<n; i++)        {            scanf("%I64d%I64d",&p[i],&a[i]);        }        LL tmp=0;        LL limited=1<<n;        for(int i=1; i<limited; i++)        {            int tot=getT(i);            LL t=solve(i);            tmp+=f(tot)*t;        }        printf("Case #%d: %I64d\n",cas,ans-tmp);    }    return 0;}
0 0
原创粉丝点击