• 3529: [Sdoi2014]数表


    Description

    有一张N×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为
    能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

    Input

    输入包含多组数据。
    输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

    Output

    对每组数据,输出一行一个整数,表示答案模2^31的值。

    Sample Input

    2

    4 4 3

    10 10 5

    Sample Output

    20

    148
    HINT

    1 < =N.m < =10^5 , 1 < =Q < =2×10^4

    这个太卡时间了,搞了我好久,不过最后跑了8s,利用了他取模的数,C++正好可以直接爆int,然后小于0就加2的31次方就行了,我就用longint强行截取了后半部分相当于爆int

    首先a[i,j]上的数我们可以看成是F[gcd(i,j)],F[i]我们都预处理出来

    然后我们要求的就是        ΣF[i]*g[i]     (F[i]<=a,g[i]是gcd=i的个数)

    所以我们要求的就是        ΣF[i]*Σtrunc(n/d)*trunc(m/d)*μ(d/i)   (F[i]<=a,i|d)

    所以我们要求的就是        Σtrunc(n/d)*trunc(m/d)*ΣF[i]*μ(d/i)   (F[i]<=a,i|d)

    因为trunc(n/d)*trunc(m/d)只有根号n级别的个数,所以我们要处理ΣF[i]*μ(d/i)的前缀和,我用的是树状数组

    然后每次询问都可以根号n*logn回答了

    但是还有一个条件,就是F[i]<=a

    前缀和还是动态的,怎么办

    首先把F[i]排序是肯定的,对于每一个i,影响到的是他的倍数,这个很麻烦啊

    于是就离线做了,把a排序,然后暴力修改前缀和,即枚举倍数

    因为排序了,所以我们最多每个i都枚举倍数一次,应该是nlognlogn的

    然后就写完了

      1 const
      2     maxn=100100;
      3     h=1<<31;
      4 type
      5     node=record
      6       n,m,a,id:longint;
      7     end;
      8 var
      9     q:array[0..maxn]of node;
     10     flag:array[0..maxn]of boolean;
     11     p,u,k,f,ans,c:array[0..maxn]of longint;
     12     t,tot,max:longint;
     13  
     14 function min(x,y:longint):longint;
     15 begin
     16     if x<y then exit(x);
     17     exit(y);
     18 end;
     19  
     20 procedure swap(var x,y:longint);
     21 var
     22     t:longint;
     23 begin
     24     t:=x;x:=y;y:=t;
     25 end;
     26  
     27 procedure swap(var x,y:node);
     28 var
     29     t:node;
     30 begin
     31     t:=x;x:=y;y:=t;
     32 end;
     33  
     34 procedure sort(l,r:longint);
     35 var
     36     i,j:longint;
     37     y:int64;
     38 begin
     39     i:=l;
     40     j:=r;
     41     y:=f[k[(l+r)>>1]];
     42     repeat
     43       while f[k[i]]<y do
     44         inc(i);
     45       while f[k[j]]>y do
     46         dec(j);
     47       if i<=j then
     48       begin
     49         swap(k[i],k[j]);
     50         inc(i);
     51         dec(j);
     52       end;
     53     until i>j;
     54     if i<r then sort(i,r);
     55     if j>l then sort(l,j);
     56 end;
     57  
     58 procedure pre;
     59 var
     60     i,j,s:longint;
     61 begin
     62     f[1]:=1;
     63     u[1]:=1;
     64     for i:=2 to max do
     65       begin
     66         if flag[i]=false then
     67         begin
     68           inc(tot);
     69           p[tot]:=i;
     70           f[i]:=i+1;
     71           u[i]:=-1;
     72         end;
     73         for j:=1 to tot do
     74           begin
     75             if int64(i)*p[j]>max then break;
     76             flag[i*p[j]]:=true;
     77             if i mod p[j]=0 then
     78               begin
     79                 s:=p[j];
     80                 while i mod (int64(s)*p[j])=0 do
     81                   s:=s*p[j];
     82                 if s=i then f[i*p[j]]:=(s*p[j]*p[j]-1)div(p[j]-1)
     83                 else f[i*p[j]]:=f[i div s]*f[s*p[j]];
     84                 break;
     85               end
     86             else
     87               begin
     88                 f[i*p[j]]:=f[i]*(p[j]+1);
     89                 u[i*p[j]]:=-u[i];
     90               end;
     91           end;
     92       end;
     93     for i:=1 to max do
     94       k[i]:=i;
     95     sort(1,max);
     96 end;
     97  
     98 procedure sort2(l,r:longint);
     99 var
    100     i,j,y:longint;
    101 begin
    102     i:=l;
    103     j:=r;
    104     y:=q[(l+r)>>1].a;
    105     repeat
    106       while q[i].a<y do
    107         inc(i);
    108       while q[j].a>y do
    109         dec(j);
    110       if i<=j then
    111       begin
    112         swap(q[i],q[j]);
    113         inc(i);
    114         dec(j);
    115       end;
    116     until i>j;
    117     if i<r then sort2(i,r);
    118     if j>l then sort2(l,j);
    119 end;
    120  
    121 procedure init;
    122 var
    123     i:longint;
    124 begin
    125     read(t);
    126     for i:=1 to t do
    127       begin
    128         read(q[i].n,q[i].m,q[i].a);
    129         q[i].id:=i;
    130         if q[i].n>q[i].m then swap(q[i].n,q[i].m);
    131         if max<q[i].n then max:=q[i].n;
    132       end;
    133     sort2(1,t);
    134 end;
    135  
    136 procedure add(x,y:longint);
    137 begin
    138     while x<=100000 do
    139       begin
    140         c[x]:=longint(int64(c[x])+y);
    141         x:=x+(x and (-x));
    142       end;
    143 end;
    144  
    145 function sum(x:longint):longint;
    146 begin
    147     sum:=0;
    148     while x>0 do
    149       begin
    150         sum:=longint(int64(sum)+c[x]);
    151         x:=x-(x and (-x));
    152       end;
    153 end;
    154  
    155 procedure main;
    156 var
    157     i,j,kk,s,lasta,s1,s2:longint;
    158 begin
    159     lasta:=1;
    160     for i:=1 to t do
    161       begin
    162         while (lasta<=max) and (f[k[lasta]]<=q[i].a) do
    163           begin
    164             s:=k[lasta];
    165             j:=1;
    166             while s<=max do
    167               begin
    168                 if u[j]<>0 then add(s,f[k[lasta]]*u[j]);
    169                 inc(s,k[lasta]);
    170                 inc(j);
    171               end;
    172             inc(lasta);
    173           end;
    174         kk:=1;
    175         while kk<=q[i].n do
    176           begin
    177             s1:=q[i].n div kk;
    178             s2:=q[i].m div kk;
    179             s:=min(trunc(q[i].n/s1),trunc(q[i].m/s2));
    180             ans[q[i].id]:=longint(int64(ans[q[i].id])+int64(longint(int64(s1)*s2))*longint(int64(sum(s))-sum(kk-1)));
    181             kk:=s+1;
    182           end;
    183       end;
    184     for i:=1 to t do
    185       if ans[i]<0 then writeln(ans[i]+h)
    186       else writeln(ans[i]);
    187 end;
    188  
    189 begin
    190     init;
    191     pre;
    192     main;
    193 end.
    View Code
  • 相关阅读:
    linux 查看系统版本
    SSL协议详解
    DIV+CSS圆角边框
    初识CoreData与详解
    initWithCoder: 与initWithFrame:的区别
    RAC初体验
    NSNotificationKVOlockdelegate的区别和用法
    Objective-O Runtime 运行时初体验
    UUID
    Swift微博编写感
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3754593.html
Copyright © 2020-2023  润新知