• [NOI2010][bzoj2005] 能量采集 [欧拉函数+分块前缀和优化]


    题面:

    传送门

    思路:

    稍微转化一下,可以发现,每个植物到原点连线上植物的数量,等于gcd(x,y)-1,其中xy是植物的横纵坐标

    那么我们实际上就是要求2*sigma(gcd(x,y))-n*m了

    又有某不知名神奇定理:一个数的所有因子的phi之和等于这个数本身,其中phi是欧拉函数

    因此题目转化为求如下:

     

    我们把式子变个型,就成了如下式子:

    然后一个前缀和优化,O(n+sqrt(n))解决

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define ll long long
     6 using namespace std;
     7 inline ll read(){
     8     ll re=0,flag=1;char ch=getchar();
     9     while(ch>'9'||ch<'0'){
    10         if(ch=='-') flag=-1;
    11         ch=getchar();
    12     }
    13     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    14     return re*flag;
    15 }
    16 ll phi[100010],pri[100010],cnt,pre[100010];
    17 void init(){
    18     phi[1]=pre[1]=1;ll i,j,k;
    19     for(i=2;i<=100010;i++){
    20         if(!phi[i]) phi[i]=i-1,pri[++cnt]=i;
    21         for(j=1;(j<=cnt)&&(i*pri[j]<=100010);j++){
    22             if(i%pri[j]) phi[i*pri[j]]=phi[i]*(pri[j]-1);
    23             else{phi[i*pri[j]]=phi[i]*pri[j];break;}
    24         }
    25         pre[i]=pre[i-1]+phi[i];
    26 //        if(i<=10) cout<<"phi "<<i<<" "<<phi[i]<<"
    ";
    27     }
    28 }
    29 ll n,m;ll ans;
    30 int main(){
    31     init();ll i,j;
    32     n=read();m=read();
    33     if(n>m) swap(n,m);
    34     for(i=1;i<=n;i=j+1){
    35         j=min(n/(n/i),m/(m/i));
    36         ans+=(ll)(n/i)*(m/i)*(pre[j]-pre[i-1]);
    37     }
    38     printf("%lld
    ",ans*2-n*m);
    39 }

    ni=1mi=1d|md|ndphi(d)

    ni=1mi=1d|md|ndphi(d)

  • 相关阅读:
    SQL中 patindex函数的用法
    纵表与横表互转的SQL
    几种数据库的大数据批量插入【转】
    使用cmd命令行窗口操作SqlServer
    C#性能优化实践
    C# 图像处理(二)—— 黑白效果
    SQLSERVER系统视图
    SQLServer行列转换 Pivot UnPivot
    C#图片处理常见方法性能比较
    GSM局数据制作1(Erision)
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8490836.html
Copyright © 2020-2023  润新知