zoukankan      html  css  js  c++  java
  • HDU 5768 Lucky7 CRT + 容斥 + 二进制枚举

    题目
    题意:
    对于7的倍数是一个幸运数字,但是给出了n个m和a,如果说一个数x满足(x equiv a_i(mod m_i)),那就不是幸运数字
    ([x,y])区间里幸运数字的个数
    单考虑([x,y])里7的倍数,y / 7 - (x - 1) / 7
    而对于n个条件,二进制枚举配合容斥,求出每个枚举的集合的CRT,但是,这CRT还得是7的倍数,那就用EXCRT,加入(xequiv 0(mod 7))这个条件即可
    那么求出了最小正整数st,因为CRT是有一个周期(T = LCM(m_i))的,所以根据前缀和,求([1,n])满足(x = st + tT, tin Z^+)的数字个数,那么每次的容斥值就是cal(y) - cal(x - 1)

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #define ll long long
    using namespace std;
    const int N = 1e5 + 5;
    void ex_gcd(ll a, ll b, ll &d, ll &x, ll &y){
        if(b == 0){
            d = a,x = 1,y = 0;
            return;
        }
        ex_gcd(b, a%b, d, y, x);
        y -= x * (a / b);
    }
    ll mull(ll a,ll b,ll mod){
        ll ans = 0;
        while(b){
            if(b & 1)ans = (ans + a) % mod;
            a = (a + a) % mod;
            b >>= 1;
        }
        return ans;
    }
    ll ex_china(vector<ll> a, vector<ll> m, int n){//x = a(mod m)
        ll M = m[0];
        ll ans = a[0];
        ll d, x, y;
        for(int i = 1; i < n; i++){
            ll c = ((a[i] - ans) % m[i] + m[i]) % m[i];
            ex_gcd(M, m[i], d, x, y);
            if(c % d)return -1;//不存在解的情况
            ll mod = m[i] / d;
            x = mull(x, c / d, mod);
            ans += x * M;
            M *= mod;
            ans = (ans % M + M) % M;
        }
        return ans > 0?ans:ans + M;//注意ans是M倍数时输出M
    }
    ll GCD(ll a, ll b){
        return b == 0 ? a : GCD(b, a % b);
    }
    ll LCM(ll a, ll b){
        return a / GCD(a, b) * b;
    }
    ll cal(ll st, ll T, ll n){//[1, n]里
        return (n - st) / T + (n >= st);
    }
    void solve(){//答案是[x, y]里7的倍数 - n个中国剩余定理
        int n; ll x, y;
        scanf("%d%lld%lld", &n, &x, &y);
        ll a[16], m[16];
        for(int i = 0; i < n; i++)
            scanf("%lld%lld", &m[i], &a[i]);
    
        ll ans = y / 7 - (x - 1) / 7;//[x, y]里7的倍数
        ll ans1 = 0;
        for(int i = 1; i < (1 << n); i++){//
            int k = 0;
            ll lcm = 1;
            std::vector<ll> mm, aa;
            for(int j = 0; j < n; j++){
                if(i & (1 << j)){
                    k++; lcm = LCM(m[j], lcm);
                    mm.push_back(m[j]); aa.push_back(a[j]);
                }
            }
            lcm = LCM(lcm, 7);
            mm.push_back(7), aa.push_back(0);
            ll chi = ex_china(aa, mm, k + 1);
            chi = cal(chi, lcm, y) - cal(chi, lcm, x - 1);
            if(k & 1)ans1 += chi;
            else ans1 -= chi;
        }
        printf("%lld
    ", ans - ans1);
    }
    int main(){
        int T;
        scanf("%d", &T);
        for(int tt = 1; tt <= T; tt++)
            printf("Case #%d: ", tt), solve();
        return 0;
    }
    
    
  • 相关阅读:
    自动化测试selenium教程
    Java开发.gitignore文件包含.iml,.log的看法
    基于接口设计与编程
    搭建大众点评CAT监控平台
    正确的打日志姿势
    【每天一条Linux指令-Day1】kill掉多个mysql的进程
    一道SQL面试题——表行列数据转换(表转置)
    @SuppressWarnings注解用法详解
    Spring IoC的底层技术支持——Java反射机制
    出现java.lang.NoSuchMethodError错误的原因
  • 原文地址:https://www.cnblogs.com/Emcikem/p/12835893.html
Copyright © 2011-2022 走看看