• [BZOJ2005][NOI2010]能量采集


    听小乐乐的去做NOI了~(≧▽≦)/~啦啦啦

    一开始sha bi了,没考虑2,3->4,6。。。样例骗人QAQ

    容易得到答案就是∑i(1<=i<=n)∑j(1<=j<=m)gcd(i,j)*2-1

    但暴力是nm的,GG

    我们转换一下思路,设f[i]为gcd为i的点对个数,怎么求f[i]呢?直接算好像并不行,考虑容斥,显然(n/i)*(m/i)就是有公因数为i的点对个数,然后减去f[2*i],f[3*i]...就好了

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    typedef long long LL;
    using namespace std;
    const int N=100010;
    LL n,m,k,ans,f[N];
    LL read() {LL d=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;}
    void judge(){freopen(".in","r",stdin); freopen(".out","w",stdout);}
    int main()
    {
        //judge();
        n=read(); m=read(); int ljj=max(n,m),pjy=min(n,m);
        for (int i=ljj;i>=1;i--)
        {
            f[i]=(n/i)*(m/i);
            for (int j=2*i;j<=pjy;j+=i)
                f[i]-=f[j];
        }
        for (LL i=1;i<=ljj;i++)
            ans+=f[i]*(2*i-1);
        printf("%lld",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    排序小结
    递推
    基准线
    毫无思绪
    计蒜客A
    尼克的任务
    售货员的难题
    Renting Boats
    工业物联网实践指南----专注生产制造活动
    阿里云单域名免费SSL证书安装
  • 原文地址:https://www.cnblogs.com/lujiaju6555/p/6791292.html
Copyright © 2020-2023  润新知