• bzoj 3944: Sum


    传说中的杜教筛,,,

    其实就是用狄利克雷卷构造出一个好求的东西,然后表示出要求的东西(好简单啊看起来2333)

    虚的不行,这些东西肯定2天之后就什么都不知道了2333

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 
     5 
     6 int n,m,cnt,prime[10000000+5]; 
     7 LL phi[10000000+5];
     8 int mo[10000000+5]; 
     9 
    10 void mobius()
    11 {
    12     phi[1]=mo[1]=1; m=10000000;
    13     for (int i=2; i<=m; i++)
    14     {
    15         if (!phi[i]) phi[i]=i-1,mo[i]=-1,prime[++cnt]=i;
    16         for (int j=1; j<=cnt && i*prime[j]<=m; j++)
    17         {
    18             if (i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1),mo[i*prime[j]]=-mo[i];
    19             else {phi[i*prime[j]]=phi[i]*prime[j],mo[i*prime[j]]=0; break;}
    20         }
    21     }
    22     for (int i=1; i<=m; i++) phi[i]+=phi[i-1];
    23     for (int i=1; i<=m; i++) mo[i]+=mo[i-1];
    24 }
    25 
    26 map<int , LL > p,q;
    27 map<int , bool > vis;
    28 LL get_phi(int x){return (x<=m)?phi[x]:p[x];}
    29 LL get_mo(int x){return (x<=m)?mo[x]:q[x];}
    30 void solve(int x)
    31 {
    32     if (x<=m) return; 
    33     int j=1,i;
    34     if (vis[x]) return; vis[x]=1;
    35     p[x]=((LL)x+1)*x>>1; q[x]=1;
    36     while (j<x)
    37     {
    38         i=j+1; j=x/(x/i); solve(x/i);
    39         p[x]-=get_phi(x/i)*(j-i+1); q[x]-=get_mo(x/i)*(j-i+1);
    40     }
    41 }
    42 int main()
    43 {
    44     int T;
    45     scanf("%d",&T); 
    46     mobius();
    47     while (T--)
    48     {
    49         scanf("%d",&n); vis.clear();
    50         if (n<=m) printf("%lld %lld
    ",phi[n],mo[n]);
    51         else{
    52             solve((LL)n); printf("%lld %lld
    ",p[n],q[n]);
    53         }
    54     }
    55     return 0;
    56 } 
  • 相关阅读:
    .editorconfig
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    《大道至简》读后感
    每日日报
    每日日报
    每日日报
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6701395.html
Copyright © 2020-2023  润新知