zoukankan      html  css  js  c++  java
  • hdu 4135 容斥

    题意:求解区间a~b与n互质数的个数

    题解:转化为1~b与n互质数减去1~a与n互质数的个数,典型的容斥。(由于这里数据范围太大,莫比乌斯就不适用了,直接用容斥枚举质数的组合,负责都根号n)

    补充:2017.8.18 多校的容斥没写出来,整理一下。一般容斥的思路,求解逆问题。这道题目的逆问题就是不与n互质的数。这里有一个点,我们判断两个数是否互素,只要看把这两个

    数唯一分解之后有没有相同的素因子。

    ac代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    typedef long long ll;
    ll a,b,n;
    //ll num[100001],vis[100001];
    vector<ll>flag;
    vector<ll>deg;
    ll prime[100001];
    void deal()
    {
        int ret=0;
        flag.clear();
        deg.clear();
        for(int i=2;i*i<=n;i++)//得到n的素因子
        {
            if(n%i==0)
            {
                prime[ret++]=i;
                while(n%i==0) n/=i;
            }
        }
        if(n>1) prime[ret++]=n;

    for(int i=1;i<(1<<ret);i++) { ll cnt=0; ll temp=1; for(int j=0;j<ret;j++) { if(i&(1<<j)) { cnt++; temp*=prime[j]; } } // cout<<temp<<' '; flag.push_back(cnt); deg.push_back((b/temp)-((a-1)/temp));// 这个细节注意一下,区间的开闭,,错了好几次! } } int main() { int t,Case=0; scanf("%d",&t); while(t--) { scanf("%lld %lld %lld",&a,&b,&n); deal(); // cout<<endl; ll ans=0; int len=flag.size(); for(int i=0;i<len;i++) { //if(flag[i]==0) continue; if(deg[i] > b) break; if(flag[i]%2) ans+=deg[i]; else ans-=deg[i]; } ll zz=b-a+1; printf("Case #%d: %lld ",++Case,zz-ans); } return 0; }
  • 相关阅读:
    android闹钟小案例之知识点总结
    转载---程序员发展之路
    android闹钟小案例之功能阐述
    基础篇:2.熟练掌握相关监听器的注册和使用
    基础篇:1.掌握基本组件和容器组件的使用
    微博分享、注销功能的实现
    新浪微博授权认证的实现
    新浪微博分享功能的简单实现
    读《编程高手箴言》笔记一
    Spark内核架构核心组件.txt
  • 原文地址:https://www.cnblogs.com/z1141000271/p/7337680.html
Copyright © 2011-2022 走看看