nefu 1315 BD的难题2

题目链接

哇 这个标题我以为是前一道题的加强版 结果没想到比第一题简单多了。

慢慢推出规律来

设输入的数为m

那么


注意这个和会爆int  

因为long long wa了好几发。。。。

#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
ll tt[1000005];
const int maxn=1e5;
int prime[maxn];
int vis[maxn],cnt,p;
void init()
{
    cnt = 0;
    memset(vis,0,sizeof(vis));
    for(int i=2; i<maxn; i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            for(int j=i+i; j<maxn; j+=i)
                vis[j]=1;
        }
    }
}
int quick(int m,int n)
{
    int ans=1;
    while(n)
    {
        if(n&1)
            ans=ans*m;
        m=m*m;
        n>>=1;
    }
    return ans;
}
void init1(int m)
{
    tt[1]=m-1;
    for(int j=2; j<=m; j++)
    {
        int x=j;
        int ans=1;
        for(int i=0; prime[i]*prime[i]<=j; i++)
        {
            if(j%prime[i]==0)
            {
                int tmp=0;
                while(x%prime[i]==0)
                {
                    tmp++;
                    x/=prime[i];
                }
                ans*=(quick(prime[i],tmp+1)-1)/(prime[i]-1);
            }
        }
        if(x>1)
        {
            ans=ans+ans*x;
        }
        tt[j]=tt[j-1]+m-ans;
    }
}
int main()
{
    int t,m;
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%d",&m);
        init1(m);
        for(int i=1; i<=m-1; i++)
        {
            printf("%lld ",tt[i]);
        }
      printf("%lld\n",tt[m]);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/yangdelu855/article/details/79176109