洛谷P3312

Portal

Solution

(T(Tleq2 imes10^4))组测试数据。给出(n,m(n,mleq10^5),a(aleq10^9)),求$$ sum_{i=1}nsum_{j=1}m [sigma_1(gcd(i,j))leq a]sigma_1(gcd(i,j)) $$

Solution

[egin{align*} ans &= sum_{i=1}^nsum_{j=1}^m [sigma_1(gcd(i,j))leq a]sigma_1(gcd(i,j)) \ &= sum_{d=1}^{+∞} [sigma_1(d)leq a]sigma_1(d) sum_{i=1}^nsum_{j=1}^m [gcd(i,j)=d] \ &= sum_{d=1}^{+∞} [sigma_1(d)leq a]sigma_1(d) sum_{d_1=1}^{+∞} mu(d_1)⌊frac{n}{dd_1}⌋⌊frac{m}{dd_1}⌋ \ &= sum_{d=1}^{+∞} ⌊frac{n}{d}⌋⌊frac{m}{d}⌋ sum_{d_1|d} [sigma_1(d_1)leq a]sigma_1(d_1)mu(frac{d}{d_1}) end{align*}$$ 将测试数据按$a$由小到大排序,维护$f(x)=sum_{d|x} [sigma_1(d)leq a]sigma_1(d)mu(dfrac{x}{d})$的前缀和。当$a$由$a_1$增大至$a_2$时,对于$d$满足$sigma_1(d)in(a_1,a_2]$,将$sigma_1(d)mu(k)$加到$f(kd)$中。预处理出$sigma_1(x),mu(x)$,用树状数组维护$f(x)$的前缀和即可。 > 时间复杂度$O(n+Tsqrt n+nlogn)$。 ##Code ```cpp //[SDOI2014]数表 #include <algorithm> #include <cstdio> using namespace std; inline char gc() { static char now[1<<16],*s,*t; if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;} return *s++; } inline int read() { int x=0; char ch=gc(); while(ch<'0'||'9'<ch) ch=gc(); while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc(); return x; } const int N=1e5+10; const int N1=1e5; int pCnt,pr[N],p1[N]; bool pNot[N]; int mu[N]; struct rec{int v,id;} f[N]; bool cmpV(rec x,rec y) {return x.v<y.v;} void init(int n) { mu[1]=1,f[1].v=1; for(int i=1;i<=n;i++) f[i].id=i; for(int i=2;i<=n;i++) { if(!pNot[i]) { pr[++pCnt]=i; p1[i]=i; mu[i]=-1,f[i].v=i+1; for(long long j=1LL*i*i;j<=n;j*=i) f[j].v=f[j/i].v*i+1; } for(int j=1;j<=pCnt;j++) { int x=i*pr[j]; if(x>n) break; pNot[x]=true; if(i%pr[j]) p1[x]=pr[j],mu[x]=-mu[i],f[x].v=f[i].v*(pr[j]+1); else {p1[x]=p1[i]*pr[j],f[x].v=f[x/p1[x]].v*f[p1[x]].v; break;} } } sort(f+1,f+n+1,cmpV); } struct query{int n,m,a,id;} q[20010]; bool cmpA(query x,query y) {return x.a<y.a;} int tr[N]; void add(int x,int v) {while(x<=N1) tr[x]+=v,x+=x&(-x);} int sum(int x) {int r=0; while(x) r+=tr[x],x-=x&(-x); return r;} int ans[20010]; int main() { int Q=read(); init(N1); for(int i=1;i<=Q;i++) q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i; sort(q+1,q+Q+1,cmpA); for(int i=1,j=1;i<=Q;i++) { int n=q[i].n,m=q[i].m,a=q[i].a; while(j<=1e5&&f[j].v<=a) { int d1=f[j].id; for(int k=1;k*d1<=1e5;k++) add(k*d1,f[j].v*mu[k]); j++; } if(n>m) swap(n,m); int res=0; for(int L=1,R;L<=n;L=R+1) { int v1=n/L,v2=m/L; R=min(n/v1,m/v2); res+=v1*v2*(sum(R)-sum(L-1)); } ans[q[i].id]=res&2147483647; } for(int i=1;i<=Q;i++) printf("%d ",ans[i]); return 0; } ``` ##P.S. 答案对$2147483647$取模,这就相当于自然溢出然后`&2147483647`。]

原文地址:https://www.cnblogs.com/VisJiao/p/LgP3312.html