SSL P2667 呵呵

来源:互联网 发布:单色led显示屏软件 编辑:程序博客网 时间:2024/05/19 22:52

题目大意:
这天,小A得到了一个序列a[1],a[2]…a[n],他想知道有多少个二元组(i,j)满足i!=j且a[i]是a[j]的因数。

对于前30%的数据,n,k<=1000.
对于100%的数据,n<=2000000,a[i]<=2000000。

题解:
枚举:
因为a[i]最大是2000000,所以扔进一个桶里,
sum[i]表示a[]里面i这个数出现了多少次
然后每次枚举一个a[i]
我们用个p[a[i]]记录这个数的贡献是否被用了。
然后
对于一个ai
他的贡献就是
①sum[ai]*sum[aj] 它的倍数给它的贡献,aj表示的ai倍数
②sum[ai] * (sum[ai]-1) 自身的贡献
①+②就是ai的贡献,然后相同的ai只需要计算一次

var    a,sum,p:array [0..2000001] of longint;    ans,i,j,n,max:longint;begin    readln(n);    for i:=1 to n do    begin         read(a[i]);         inc(sum[a[i]]);         if a[i]>max then max:=a[i];    end;    for i:=1 to n do      begin           if (p[a[i]]=0) and (a[i]<>0) then             begin                  p[a[i]]:=1;                  ans:=ans+sum[a[i]]*(sum[a[i]]-1);                  j:=a[i];                  while j+a[i]<=max do                  begin                       j:=j+a[i];                       ans:=ans+sum[j]*sum[a[i]];                  end;             end;      end;    writeln(ans);end.