SDOI 2014 数表 题解
題目傳送門
題目大意: 設 s(i,j)=∑d∣i,d∣jds(i,j)=\sum_{d|i,d|j}ds(i,j)=∑d∣i,d∣j?d,求 ∑i=1n∑j=1ms(i,j)[s(i,j)≤a]\sum_{i=1}^n \sum_{j=1}^m s(i,j)[s(i,j)\leq a]∑i=1n?∑j=1m?s(i,j)[s(i,j)≤a]。
題解
顯然 s(i,j)=∑d∣i,d∣jd=∑d∣gcd?(i,j)d=σ1(gcd?(i,j))s(i,j)=\sum_{d|i,d|j}d=\sum_{d|\gcd(i,j)}d=\sigma_1(\gcd(i,j))s(i,j)=∑d∣i,d∣j?d=∑d∣gcd(i,j)?d=σ1?(gcd(i,j)),那么原柿子變為:
=∑i=1n∑j=1mσ1(gcd?(i,j))[σ1(gcd?(i,j))≤a]=\sum_{i=1}^n \sum_{j=1}^m \sigma_1(\gcd(i,j))[\sigma_1(\gcd(i,j))\leq a] =i=1∑n?j=1∑m?σ1?(gcd(i,j))[σ1?(gcd(i,j))≤a]
設 f(d)f(d)f(d) 表示有多少對 i,ji,ji,j 的 gcd?\gcdgcd 為 ddd,F(n)F(n)F(n) 表示有多少對 i,ji,ji,j 的 gcd?\gcdgcd 是 nnn 的倍數,那么有:
F(n)=∑n∣df(d)F(n)=\sum_{n|d} f(d) F(n)=n∣d∑?f(d)
考慮莫比烏斯反演,反演一下上面的柿子得到:
f(d)=∑d∣nF(n)μ(nd)f(d)=\sum_{d|n} F(n)\mu(\frac n d) f(d)=d∣n∑?F(n)μ(dn?)
轉化一下原來的柿子,可以得到:
=∑i=1min?(n,m)σ1(i)[σ1(i)≤a]×f(i)=∑i=1min?(n,m)σ1(i)[σ1(i)≤a]×∑i∣pF(p)μ(pd)=\sum_{i=1}^{\min(n,m)} \sigma_1(i) [\sigma_1(i)\leq a] \times f(i)\\ =\sum_{i=1}^{\min(n,m)} \sigma_1(i) [\sigma_1(i)\leq a] \times \sum_{i|p} F(p)\mu(\frac p d) =i=1∑min(n,m)?σ1?(i)[σ1?(i)≤a]×f(i)=i=1∑min(n,m)?σ1?(i)[σ1?(i)≤a]×i∣p∑?F(p)μ(dp?)
設 j=pdj=\frac p dj=dp?,更換枚舉對象,有:
=∑i=1min?(n,m)σ1(i)[σ1(i)≤a]×∑j=1?min?(n,m)i?F(ij)μ(j)=\sum_{i=1}^{\min(n,m)} \sigma_1(i) [\sigma_1(i)\leq a] \times \sum_{j=1}^{\lfloor \frac {\min(n,m)} {i} \rfloor} F(ij)\mu(j) =i=1∑min(n,m)?σ1?(i)[σ1?(i)≤a]×j=1∑?imin(n,m)???F(ij)μ(j)
根據莫比烏斯反演的一般思想:兩個變量乘在一起是不好看的。于是設 k=ijk=ijk=ij,更換枚舉對象,有:
∑k=1min?(n,m)F(k)∑i∣kσ1(i)[σ1(i)≤a]μ(ki)\sum_{k=1}^{\min(n,m)}F(k) \sum_{i|k} \sigma_1(i)[\sigma_1(i)\leq a] \mu(\frac ki) k=1∑min(n,m)?F(k)i∣k∑?σ1?(i)[σ1?(i)≤a]μ(ik?)
顯然,F(k)=?nk??mk?F(k)=\lfloor \frac n k \rfloor \lfloor \frac m k \rfloorF(k)=?kn???km??,設 g(k)=∑i∣kσ1(i)[σ1(i)≤a]μ(ki)g(k)=\sum_{i|k} \sigma_1(i)[\sigma_1(i)\leq a] \mu(\frac ki)g(k)=∑i∣k?σ1?(i)[σ1?(i)≤a]μ(ik?),帶進去得:
∑k=1min?(n,m)?nk??mk?g(k)\sum_{k=1}^{\min(n,m)}\lfloor \frac n k \rfloor \lfloor \frac m k \rfloor g(k) k=1∑min(n,m)??kn???km??g(k)
因為 aaa 會變,也就是說 g(k)g(k)g(k) 是會變的,只有當 σ1(i)≤a\sigma_1(i)\leq aσ1?(i)≤a 時,σ1(i)\sigma_1(i)σ1?(i) 才會產生貢獻。因為 σ1(i)\sigma_1(i)σ1?(i) 是不會變的,所以將上面的柿子移個項,a≥σ1(i)a \geq \sigma_1(i)a≥σ1?(i),那么如果 aaa 是嚴格不下降的,那么 σ1(i)\sigma_1(i)σ1?(i) 的貢獻就有了單調性。
那么我們可以將 σ1(i)\sigma_1(i)σ1?(i) 和所有詢問排序,詢問按 aaa 排序,那么每次動態更新 g(k)g(k)g(k) 即可。
因為求解的時候需要求出 g(k)g(k)g(k) 的前綴和,而這個前綴和會隨著 g(k)g(k)g(k) 的更新有很大的改動,所以我們需要用一個樹狀數組來維護 g(k)g(k)g(k) 的前綴和。
代碼如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define maxn 100010 #define ll long long #define mod 2147483648llint t; struct que{int n,m,a,pos;}; que ask[20010]; int low[maxn],prime[maxn],tt=0,mu[maxn]; bool v[maxn]; struct node{int x,y;}; node sigma[maxn]; bool cmp1(node x,node y){return x.y<y.y;} bool cmp2(que x,que y){return x.a<y.a;} void work() {mu[1]=1;for(int i=2;i<=maxn-10;i++){if(!v[i])prime[++tt]=i,mu[i]=-1;for(int j=1;j<=tt&&i*prime[j]<=maxn-10;j++){v[i*prime[j]]=true;if(i%prime[j]==0)break;mu[i*prime[j]]=-mu[i];}}for(int i=1;i<=maxn-10;i++){sigma[i].x=i;for(int j=1;i*j<=maxn-10;j++)sigma[i*j].y+=i;}sort(sigma+1,sigma+maxn-10+1,cmp1); } ll tr[maxn]; inline int lowbit(int x){return x&(-x);} void add(int x,ll y) {for(;x<=maxn-10;x+=lowbit(x))tr[x]=(tr[x]+y)%mod; } ll sum(int x) {ll re=0;for(;x>=1;x-=lowbit(x))re=(re+tr[x])%mod;return re; } ll anss[20010];int main() {work();scanf("%d",&t);for(int i=1;i<=t;i++)scanf("%d %d %d",&ask[i].n,&ask[i].m,&ask[i].a),ask[i].pos=i;sort(ask+1,ask+t+1,cmp2);int now=1;for(int i=1;i<=t;i++){while(sigma[now].y<=ask[i].a&&now<=maxn-10){for(int j=1;sigma[now].x*j<=maxn-10;j++)add(sigma[now].x*j,(ll)sigma[now].y*mu[j]);now++;}int n=ask[i].n,m=ask[i].m,l=1,r;ll ans=0;while(l<=min(n,m)){r=min(n/(n/l),m/(m/l));ans=(ans+(sum(r)-sum(l-1)+mod)%mod*(ll)(n/l)*(ll)(m/l))%mod;l=r+1;}anss[ask[i].pos]=ans;}for(int i=1;i<=t;i++)printf("%lld\n",anss[i]); }總結
以上是生活随笔為你收集整理的SDOI 2014 数表 题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySql自动同步主库数据(Canal)
- 下一篇: Word默认打开方式不对,图标空白的修复