洛谷 P3312 [SDOI2014]数表

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

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

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

错误记录:

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\n",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\n",an);
128     }
129     for(i=1;i<=qq;i++)    printf("%lld\n",ans[i]%md);
130     return 0;
131 }

猜你喜欢

转载自www.cnblogs.com/hehe54321/p/9380546.html