• 洛谷 P3312 [SDOI2014]数表


    式子化出来是$sum_{T=1}^m{lfloor}frac{n}{T}{ floor}{lfloor}frac{m}{T}{ floor}sum_{k|T}mu(frac{T}{k})[sigma(k)<=a]sigma(k)$

    如果没有a的限制的话,显然只要把后面那个sigma预处理出来

    有了a的限制呢?考虑把询问按a从小到大排序,然后每次把所有满足$lasta<sigma(k)<=nowa$(lasta指上个询问的a,nowa指当前询问的a)的加入后面那部分的贡献(开始时对于每个T预处理有哪些k满足$sigma(k)=T$,这里就暴力枚举k使得$sigma(k)$=当前要加入贡献的值,再暴力枚举k的倍数更新);用树状数组维护前缀和;复杂度是n*log^2+T*sqrt*log

    错误记录:

    1.121行<=n写成<=m;导致除以0;本地测试的时候只用了n=m的数据,所以没测出来

    2.108行没规定这个<=500000

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 using namespace std;
      6 #define fi first
      7 #define se second
      8 #define mp make_pair
      9 #define pb push_back
     10 typedef long long ll;
     11 typedef unsigned long long ull;
     12 typedef pair<int,int> pii;
     13 const ll N=100000;
     14 const ll M=100000;
     15 struct Q
     16 {
     17     ll n,m,a,num;
     18 }q[M+100];
     19 ll qq;
     20 ll ans[M+100];
     21 ll mu[N+100],len,prime[N+100];
     22 ll f1[N+100],f2[N+100],h[N+100];
     23 //分别为最小质因子的p^k,1+p^0+p^1+..+p^k,函数值
     24 vector<int> dd[501000];
     25 bool nprime[N+100];
     26 bool c1(const Q &a,const Q &b)    {return a.a<b.a;}
     27 const ll md=1LL<<31;
     28 #define lowbit(x) ((x)&(-x))
     29 ll d[N+100];
     30 void add(ll p,ll x)
     31 {
     32     for(;p<=N;p+=lowbit(p))    d[p]+=x;
     33 }
     34 ll sum(ll p)
     35 {
     36     ll ans=0;
     37     for(;p>0;p-=lowbit(p))    ans+=d[p];
     38     return ans;
     39 }
     40 //ll Mod(ll a,ll b)
     41 //{
     42 //    if(a>=0)    return a%b;
     43 //    else if(a%b==0)    return 0;
     44 //    else    return b+a%b;
     45 //}
     46 int main()
     47 {
     48     ll i,j,k,n,m,an;
     49     mu[1]=1;h[1]=1;
     50     for(i=2;i<=N;i++)
     51     {
     52         if(!nprime[i])
     53         {
     54             prime[++len]=i;mu[i]=-1;
     55             f1[i]=i;f2[i]=i+1;h[i]=i+1;
     56         }
     57         for(j=1;j<=len&&i*prime[j]<=N;j++)
     58         {
     59             nprime[i*prime[j]]=1;
     60             if(i%prime[j]==0)
     61             {
     62                 mu[i*prime[j]]=0;
     63                 f1[i*prime[j]]=f1[i]*prime[j];
     64                 f2[i*prime[j]]=f2[i]+f1[i*prime[j]];
     65                 h[i*prime[j]]=h[i]/f2[i]*f2[i*prime[j]];
     66                 break;
     67             }
     68             else
     69             {
     70                 mu[i*prime[j]]=-mu[i];
     71                 f1[i*prime[j]]=prime[j];
     72                 f2[i*prime[j]]=1+prime[j];
     73                 h[i*prime[j]]=h[i]*f2[i*prime[j]];
     74             }
     75         }
     76     }
     77     for(i=1;i<=N;i++)
     78         dd[h[i]].pb(i);
     79     /*
     80     ll ttt=0;
     81     for(i=1;i<=20000;i++)    ttt=max(ttt,h[i]);
     82     printf("%lld",ttt);
     83     {
     84         ll a,n,m,k;
     85         while(1)
     86         {
     87             scanf("%lld%lld%lld",&n,&m,&a);
     88             if(n>m)    swap(n,m);
     89             ll ans=0;
     90             for(ll T=1;T<=m;T++)
     91             {
     92                 ll a1=0;
     93                 for(k=1;k<=T;k++)
     94                     if(T%k==0)
     95                     {
     96                         a1+=mu[T/k]*(h[k]<=a)*h[k];
     97                     }
     98                 ans+=(n/T)*(m/T)*a1;
     99             }
    100             printf("%lld
    ",ans);
    101         }
    102     }*/
    103     scanf("%lld",&qq);
    104     for(i=1;i<=qq;i++)    scanf("%lld%lld%lld",&q[i].n,&q[i].m,&q[i].a),q[i].num=i;
    105     sort(q+1,q+qq+1,c1);
    106     for(i=1,j=0;i<=qq;i++)
    107     {
    108         while(j+1<=q[i].a&&j+1<=500000)
    109         {
    110             j++;
    111             for(auto d:dd[j])
    112             {
    113                 for(k=d;k<=N;k+=d)
    114                 {
    115                     add(k,mu[k/d]*j);
    116                 }
    117             }
    118         }
    119         if(q[i].n>q[i].m)    swap(q[i].n,q[i].m);
    120         n=q[i].n;m=q[i].m;an=0;
    121         for(ll i=1,j;i<=n;i=j+1)
    122         {
    123             j=min(n/(n/i),m/(m/i));
    124             an+=(n/i)*(m/i)*(sum(j)-sum(i-1));
    125         }
    126         ans[q[i].num]=an;
    127         //printf("a%lld
    ",an);
    128     }
    129     for(i=1;i<=qq;i++)    printf("%lld
    ",ans[i]%md);
    130     return 0;
    131 }
  • 相关阅读:
    今天,我们来聊一聊互联网真的有你所期待的那么好吗?来自一个老码农的碎碎念
    新鲜出炉!阿里Java后端面经,已拿offer!
    面试阿里,字节跳动,美团必被问到的红黑树原来这么简单
    凭借着这份Spring面试题,我拿到了阿里,字节跳动美团的offer!
    深度分析:理解Java中的多态机制,一篇直接帮你掌握!
    gdb调试core dump使用
    665. Non-decreasing Array
    netstat命令详解
    ifconfig命令
    #paragma详解
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9380546.html
Copyright © 2020-2023  润新知