zoukankan      html  css  js  c++  java
  • SDOI2008仪仗队

    这题应该注意到与b2818的不同

    一个点能被看见当且仅当它与(1,1)的横纵坐标的距离gcd为1

    所以问题转化为x,y<=n-1,求gcd(x,y)=1的方案数

    最后要加上2

    代码:

     1 var i,n,tot:longint;
     2     ans:int64;
     3     phi:array[0..50000] of int64;
     4     p:array[0..50000] of longint;
     5 procedure get;
     6  var i,j:longint;
     7    begin
     8      fillchar(phi,sizeof(phi),0);
     9      tot:=0;
    10      phi[1]:=0;
    11      for i:=2 to n do
    12       if phi[i]=0 then
    13        begin
    14          phi[i]:=i-1;inc(tot);p[tot]:=i;
    15          j:=i+i;
    16          while j<=n do
    17            begin
    18              if phi[j]=0 then phi[j]:=j;
    19              phi[j]:=(phi[j] div i)*(i-1);
    20              inc(j,i);
    21            end;
    22        end;
    23    end;
    24 procedure main;
    25  begin
    26    readln(n);dec(n);
    27    get;
    28    for i:=2 to n do inc(phi[i],phi[i-1]);
    29    writeln(2*phi[n]+3);
    30  end;
    31 begin
    32   main;
    33 end.
    34               
    View Code

     学了一种新的求欧拉函数的筛法——欧拉筛法

    代码:

     1 var  i,n,tot:longint;
     2      ans:int64;
     3      fai:array[0..50000] of int64;
     4      p:array[0..50000] of longint;
     5      check:array[0..50000] of boolean;
     6 procedure getfai;
     7  var i,j,k:longint;
     8  begin
     9  tot:=0;
    10  fillchar(check,sizeof(check),false);
    11  for i:=2 to n do
    12   begin
    13   if not(check[i]) then
    14    begin
    15     inc(tot);
    16     p[tot]:=i;
    17     fai[i]:=i-1;
    18    end;
    19   for j:=1 to tot do
    20    begin
    21     k:=i*p[j];
    22     if k>n then break;
    23     check[k]:=true;
    24     if i mod p[j]=0 then
    25      begin
    26       fai[k]:=fai[i]*p[j];
    27       break;
    28      end
    29     else
    30       fai[k]:=fai[i]*(p[j]-1);
    31    end;
    32  end;
    33 end;
    34 procedure main;
    35  begin
    36  readln(n);dec(n);
    37  getfai;
    38  for i:=2 to n do inc(fai[i],fai[i-1]);
    39  writeln(2*fai[n]+3);
    40  end;
    41 begin
    42  main;
    43 end.          
    View Code

     又作了一个小优化,缩小了空间使用,去掉check数组,直接用fai是否为0来判断是否是质数

    代码:

     1 var  i,n,tot:longint;
     2      ans:int64;
     3      fai:array[0..50000] of int64;
     4      p:array[0..50000] of longint;
     5 procedure getfai;
     6  var i,j,k:longint;
     7  begin
     8  tot:=0;
     9  fillchar(fai,sizeof(fai),0);
    10  for i:=2 to n do
    11   begin
    12   if fai[i]=0 then
    13    begin
    14     inc(tot);
    15     p[tot]:=i;
    16     fai[i]:=i-1;
    17    end;
    18   for j:=1 to tot do
    19    begin
    20     k:=i*p[j];
    21     if k>n then break;
    22     if i mod p[j]=0 then
    23      begin
    24       fai[k]:=fai[i]*p[j];
    25       break;
    26      end
    27     else
    28       fai[k]:=fai[i]*(p[j]-1);
    29    end;
    30  end;
    31 end;
    32 procedure main;
    33  begin
    34  readln(n);dec(n);
    35  getfai;
    36  for i:=2 to n do inc(fai[i],fai[i-1]);
    37  writeln(2*fai[n]+3);
    38  end;
    39 begin
    40  main;
    41 end.       
    View Code
  • 相关阅读:
    壶公随感
    消息称微软受谷歌刺激 急于收购雅虎(zz)
    远程注销Windows用户
    "杀人"游戏中的一些规律
    由两点的经纬度估算距离
    我的城市?
    Blog里的一个bug,dudu看能否修正?
    这两天真烦
    发简历,找上海.Net方面软件开发工作
    "上海.NET俱乐部"聚会筹备进展
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3800092.html
Copyright © 2011-2022 走看看