• BZOJ2749: [HAOI2012]外星人


    2749: [HAOI2012]外星人

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 377  Solved: 199
    [Submit][Status]

    Description

     

    Input

     

    Output

    输出test行,每行一个整数,表示答案。

    Sample Input

    1
    2
    2 2
    3 1

    Sample Output

    3

    HINT


    Test<=50 Pi<=10^5,1<=Q1<=10^9

    Source

    题解:

    终于把这题搞掉了。。。

    研究了一下此题的两种解法。

    一种是直接求 这个数一直phi,最后能phi出多少个2,就是答案。

    一种是利用递推的思想,用 f[i]表示i phi几次能变成1,有递推式 f[i]=f[phi(i)]+1

    这两种方法都可以求出正确结果,让我们讨论一下为什么这样就可以:

    首先,

    题中给出了这样的公式,然后我们发现每次phi只能使每个质数的指数-1,然后这个 p[i]-1会继续质因数分解然后加在其它比它小的质数的指数上。

    然后我们就会发现,2被phi的次数一定是最多的!!!

    假设还有另一个质数 x 那么 phi(x)会多出1个2,所以 phi(2)的次数>=phi(x) 的次数!

    所以 2被phi了多少次,ans就是多少!2还没有被phi完,其他质数的质数就已经都为0了!

    然后呢?我们得到了一个什么结论?一个数被phi成1的次数就等于它phi了多少次2

    这样的话 f[x]就等于 x phi 2的次数。

    然后两种方法就统一了。

    这也就解释了为什么不同的质数之间的被phi的次数是可以叠加的,因为我们加的实际上是同一个质数2的次数,而phi每次只能让2的指数-1!!!

    还有一些细节要注意,这里就不提出了。

    代码:直接递推求 f[x](求phi写萎了。。。)(这里面的偶数求的会比实际少1,因为并没有计入第一次phi的2)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int m=200010;
     7 int p[m],f[m],n,t,i,j,x,y;
     8 long long ans; 
     9 int main()
    10 {
    11     for(i=1;i<=m;i++) p[i]=i;
    12     for(i=2;i<=m;i++)
    13         if(p[i]==i)
    14             for(j=i;j<=m;j+=i) p[j]=p[j]/i*(i-1);
    15     p[1]=1,f[1]=-1;
    16     for(i=2;i<=m;i++) f[i]=f[p[i]]+1;
    17     f[1]++,f[2]++; 
    18     cin>>t;
    19     while(t--)
    20     {
    21         scanf("%d",&n);
    22         for(ans=1,i=1;i<=n;i++)
    23         {
    24             scanf("%d%d",&x,&y);
    25             if(x==2) ans--;
    26             ans+=(long long)f[x]*y;
    27         }
    28         printf("%lld
    ",ans);
    29     }
    30     return 0;
    31 }
    32 
    View Code

    代码:求2的个数

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 100000+5
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0;char ch=getchar();
    27     while(ch<'0'||ch>'9'){ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x;
    30 }
    31 int tot,p[maxn],f[maxn];
    32 bool v[maxn];
    33 int main()
    34 {
    35     freopen("input.txt","r",stdin);
    36     freopen("output.txt","w",stdout);
    37     f[1]=1;
    38     for2(i,2,maxn)
    39      {
    40          if(!v[i]){p[++tot]=i;f[i]=f[i-1];}
    41          for1(j,tot)
    42           {
    43               int t=i*p[j];
    44               if(t>maxn)break;
    45               v[t]=1;
    46               f[t]=f[i]+f[p[j]];
    47               if(i%p[j]==0)break;
    48           }
    49      }
    50     int m=read();
    51     while(m--)
    52      {
    53          int n=read();ll ans=1;
    54          for1(i,n) 
    55          {
    56              int x=read(),y=read();
    57              if(x==2)ans--;
    58             ans+=(ll)f[x]*y;
    59         }
    60         printf("%lld
    ",ans);
    61     }
    62     return 0;
    63 }
    View Code

    其实f[x]=求2的个数,这里只是用了不同的方法。

  • 相关阅读:
    hdu 1253 胜利大逃亡 (三维简单bfs+剪枝)
    OpenCV中OpenCL模块函数
    基于年纪和成本(Age & Cost)的缓存替换(cache replacement)机制
    POJ 1637 混合图求欧拉回路 最大流实现
    Linux-shell-算术运算{expr、bc、dc、(( ))和[ ]}
    uboot环境变量与内核MTD分区关系
    nor flash 和nand flash 的区别
    NAND Flash大容量存储器K9F1G08U的坏块管理方法
    嵌入式学习之Nand Flash
    s3c2440对nandflash的操作
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4009085.html
Copyright © 2020-2023  润新知