zoukankan      html  css  js  c++  java
  • luogu4388 付公主的矩形

    题面:

    为了排解心中的怒气,她造了大量的稻草人来发泄。每天付公主都会把一些稻草人摆成一个RC的矩形,矩形的每个方格上都有一个稻草人。然后她站在这个矩形的左上角,向矩形的右下角射箭。付公主的箭术过人,她能穿透任意多的稻草人。弓箭经过的方格上的稻草人难逃厄运,报废掉了。看着被毁坏的稻草人,付公主开心了一些。

    但是制造稻草人需要大量的金钱,所以付公主不希望坏掉太多的稻草人,所以她每天都选择毁坏掉N个稻草人。付公主还是个喜新厌旧的人,她希望每天能看到一种不同的稻草人摆放矩形。矩形是可以旋转的,即RC和CR等价。她毫不费力地算出了摆放方案数,于是她决定刁难你一下。不甘示弱的你决定写个程序计算这个数来提交付公主的答卷。

     数学题。。。

    (懵逼*INF)

    !震惊,竟是欧拉函数!

    先分析一下,对于一对a、b,经过的格数为 a+b-gcd(a,b),具体证明:

    每向右移一个则+1;

    每向下移一个则+1;

    每经过一个整点则-1;

    因此为a+b-gcd(a,b);

    因此有n = a+b-gcd(a,b);(易证gcd是n的约数)

    同除gcd(a,b),得

    (n/gcd(a,b)) = a+b-1;(这里a = a/gcd(a,b),b = b/gcd(a,b))

    设m=n/gcd(a,b);

    m+1 = a+b;

    这里m是n的因数,a、b互质。

    找n的因数,再加一,求欧拉函数,求和。

    但是会有重复(a、b是一对),所以ans先加一再>>1。(+1是a=n,b=n只算了一次)

    代码:

    #include<cstdio>
    #define N 100000050
    int n,cri[N],phi[N],cnt;
    bool vis[N];
    int ans = 0;
    void oula()
    {
        phi[1] = 1;
        for(int i=2;i<=n+1;i++)
        {
            if(!vis[i])
            {
                phi[i]=i-1;
                cri[++cnt] = i;
            }
            if(n%(i-1)==0)ans+=phi[i];
            for(int j=1;j<=cnt&&i*cri[j]<=n+1;j++)
            {
                vis[i*cri[j]]=1;
                if(i%cri[j]==0)
                {
                    phi[i*cri[j]]=phi[i]*cri[j];
                    break;
                }else
                {
                    phi[i*cri[j]]=phi[i]*phi[cri[j]];
                }
            }
        }
    }
    int main()
    {
    //    freopen("chord.in","r",stdin);
    //    freopen("chord.out","w",stdout);
        scanf("%d",&n);
        oula();
        printf("%d
    ",(ans+1)>>1);
        return 0;
    }
  • 相关阅读:
    A Tour of Go For continued
    A Tour of Go For
    Request对象的主要方法
    JAVA中的异常疑点解析
    用JDBC如何调用存储过程
    字节流与字符流的区别
    js判断第二个日期比第一个日期大
    JAVA中会存在内存泄露吗
    mysql 建库建表建用户
    mysql 的数据类型
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9618815.html
Copyright © 2011-2022 走看看