ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU 4407 Sum 容斥原理

2020-07-03 23:35:31  阅读:183  来源: 互联网

标签:HDU gcd int ll 4407 容斥 cnt 互质 first


回忆 HDU 4135 经典题 Co-Prime 求[a,b]区间与给定素数p互质的个数。 将p质因数分解后容斥即可。 原理就是质因数的倍数就是与p不互素的数。

此题的写法:

ll p[maxn];
int cnt;
ll n;

void init(ll m) {
    for (int i = 2; i * i <= m; i++) {
        if (m % i == 0) {
            p[cnt++] = i;
            while (m % i == 0) m /= i;
        }
    }
    if (m > 1) p[cnt++] = m;
}

ll solve(ll x) {
    ll len = 1ll << cnt;
    ll ans = 0;
    for (ll i = 1; i < len; i++) {
        int f = 0;
        ll tmp = 1;
        for (ll j = 0; j < cnt; j++) {
            if (i & (1ll << j)) {
                f++;
                tmp *= p[j];
            }
        }
        if (f & 1) ans += x / tmp;
        else ans -= x/ tmp;
    }
    return ans;
}

int main() {
    int T;
    ll a, b;
    scanf("%d", &T);
    int kase = 1;
    while (T--) {
        cnt = 0;
        scanf("%lld%lld%lld", &a, &b, &n);
        init(n);
        printf("Case #%d: %lld\n", kase++, (b - a + 1) - (solve(b) - solve(a - 1)));
    }
    return 0;
}
View Code

 

而HDU4407 这题问的是区间的互质的数的和。 其实是差不多的,只不过把个数变成求和。对于分解质因数后的每个质数p,其倍数p,2p,3p.....都是与给定的数不互质的数,容斥即可。

注意 对于询问1 可以开一个map表示 a->b 的关系。每次for一遍就行。

ll a[maxn];
int cnt;

ll n, m;

map<ll, ll> mp;
ll x, y, z;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

void init(ll x) {
    cnt = 0;
    for (ll i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            a[cnt++] = i;
            while (x % i == 0) x /= i;
        }
    }
    if (x > 1) a[cnt++] = x;
}

ll solve(ll x) {
    ll ans = 0;
    for (ll i = 1; i < (1ll << cnt); i++) {
        ll sum = 1;
        int byte = 0;
        for (int j = 0; j < cnt; j++) {
            if (i & (1ll << j)) {
                byte++;
                sum *= a[j];
            }
        }
        if (byte & 1) ans += (sum + x / sum * sum) * (x / sum )/2;
        else ans -= (sum + x / sum * sum) * (x / sum) /2;
    }
    return ans;
}

int main() {
    int T;
    scanf("%d", &T);
    int k;
    while (T--) {
        mp.clear();
        scanf("%lld%lld", &n, &m);
        for (int i = 0; i < m; i++) {
            scanf("%d", &k);
            if (k == 2)  scanf("%lld%lld", &x, &y), mp[x] = y;
            else {
                scanf("%lld%lld%lld", &x, &y, &z);
                init(z);
                ll res = (y - x + 1)* (x + y) / 2 - (solve(y) - solve(x - 1));
                for (auto it = mp.begin(); it != mp.end(); it++) {
                    if (it->first >= x && it->first <= y) {
                        if (gcd(it->first, z) == 1) res -= it->first;
                        if (gcd(it->second, z) == 1) res += it->second;
                    }
                }
                printf("%lld\n", res);
            }
        }
    }
}
View Code

 

标签:HDU,gcd,int,ll,4407,容斥,cnt,互质,first
来源: https://www.cnblogs.com/hznumqf/p/13233225.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有