zoukankan      html  css  js  c++  java
  • [洛谷P4388] 付公主的矩形

    18.09.09模拟赛T1。

    一道数学题。

    题目传送门

    首先把对角线当成是某个点的移动轨迹,从左下到右上。

    那么这个点每上升一个单位长度,就穿过一个格子。

    每右移一个单位长度,也会穿过一个格子。

    例外:穿过格点,会减少穿过的格子数。

    初步的结论:R*C的矩形,对角线穿过的格子数N=R+C-gcd(R,C)。

    那么我们只需算出这个方程的解的个数。

    可以看出,R、C和gcd(R,C)都是gcd(R,C)的倍数。

    那么N显然也是。

    设N/gcd(R,C)=n,R/gcd(R,C)=r,C/gcd(R,C)=c。

    方程两边同除gcd(R,C):n=r+c-1。

    由欧几里得算法可得:gcd(n+1,r)=gcd(n+1-r,r)=gcd( (r+c-1) +1-r,r)=gcd(c,r)。

    这时候r和c一定是互质的,假如它们有公因数,在除以gcd(R,C)时就会被除掉。

    所以:gcd(r,c)=1。得:gcd(n+1,r)=1。

    即:n+1与r互质,n是N得因数。

    答案即为:

    所以我们线性筛出从2到n+1的欧拉函数phi [ i ],挑出其中i-1是n的因数的,把它们的phi [ i ]加起来就行了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int n,cnt,ans;
     7 int pr[100000005];
     8 bool v[100000005];
     9 int phi[100000005];
    10 
    11 int main()
    12 {
    13     scanf("%d",&n);
    14     for(int i=2;i<=n+1;i++)
    15     {
    16         if(!v[i])
    17         {
    18             pr[++cnt]=i;
    19             phi[i]=i-1;
    20         }
    21         if(n%(i-1)==0)ans+=phi[i];
    22         for(int j=1;(j<=cnt)&&(i*pr[j]<=n+1);j++)
    23         {
    24             v[i*pr[j]]=true;
    25             if(i%pr[j]==0)
    26             {
    27                 phi[i*pr[j]]=phi[i]*pr[j];
    28                 break;
    29             }else
    30             {
    31                 phi[i*pr[j]]=phi[i]*phi[pr[j]];
    32             }
    33         }
    34     }
    35     printf("%d",(ans+1)/2);
    36     return 0;
    37 }
  • 相关阅读:
    NOIp2018集训test-10-17 (bike day3)
    NOIp2018集训test-10-16 (bike day2)
    django简介中
    django简介上
    bootstrap
    jQuery简介
    js完整篇
    css完结
    css三
    前端二与css开篇
  • 原文地址:https://www.cnblogs.com/eternhope/p/9622542.html
Copyright © 2011-2022 走看看