[SDOI2014] number table

Topic links: the Click here Wallpaper

Solution:

In regard to the title \ (A \) limiting a look very troublesome, we first \ (A \) aside
\ [\ sum_ {i = 1 } ^ N \ sum_ {j = 1} ^ M \ sigma ( gcd (i, j)) \\
\] see the \ (GCD \) , then we think immediately enumerate
\ [\ sum_ {d = 1 } ^ N \ sigma (d) \ sum_ {i = 1 } ^ {\ lfloor \ frac {
N} {d} \ rfloor} \ sum_ {j = 1} ^ {\ lfloor \ frac {M} {d} \ rfloor} [gcd (i, j) = 1] \] become familiar expression form
\ [\ sum_ {d = 1 } ^ N \ sigma (d) \ sum_ {i = 1} ^ {\ lfloor \ frac {N} {d} \ rfloor} \ sum_ { j = 1} ^ {\ lfloor \ frac {M} {d} \ rfloor} \ sum_ {t | i} \ sum_ {t | j} \ mu (t) \\ \ sum_ {d = 1} ^ N \ sigma (d) \ sum_ {t = 1} ^ {\ lfloor \ frac {N} {d} \ rfloor} \ mu (t) \ lfloor \ frac {N} {dt} \ rfloor \ lfloor \ frac {M} {dt} \ rfloor \\ \]
order \ (T dt = \)
\ [\ sum_. 1 = {T} ^ N \ lfloor \ FRAC {N} {} T \ rfloor \ lfloor \ FRAC {T} {M} \ rfloor \ sum_ {d | T
} \ sigma (d) \ mu ({T \ over d}) \] order\ (F (T) = \ sum_ {D | T} \ Sigma (D) \ MU ({T \ over D}) \) , this function can be pre-processed, and then to block number theory

Consider about \ (a \) restrictions, in fact, there \ (a \) in the case of restrictions, it will only change \ (f (T) \) values

When \ (\ sigma (d)> a \) when, \ (\ Sigma (d) \) does not \ (f (T) \) caused by the contribution, then we use a tree-like array to maintain \ (f \) value

We ask follow \ (a \) values are sorted, each time the number of new add to the mix, enumerate multiple of it, plus the contribution can be, for each number is \ (\ log ^ 2 n \ )

Then process block number theory, the Fenwick tree and can query section, each asking for the \ (\ sqrt n \ log n \)

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+11;
const int mod=2147483647;
struct Gval{int v,id;}g[N];
struct Ask{int qn,qm,qa,id;}a[N];
int n,m,cnt,vis[N],p[N],lst=1;
int num[N],u[N],tr[N],ans[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void prepare(){
    u[1]=1;g[1].v=1;g[1].id=1;num[1]=1;
    for(int i=2;i<N;i++){
        g[i].id=i;
        if(!vis[i]) p[++cnt]=i,u[i]=-1,g[i].v=i+1,num[i]=i;
        for(int j=1;j<=cnt&&i*p[j]<N;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0){
                num[i*p[j]]=num[i]*p[j];
                if(i*p[j]==num[i*p[j]]) g[i*p[j]].v=g[i].v+i*p[j];
                else g[i*p[j]].v=g[i/num[i]].v*g[num[i*p[j]]].v;
                break;
            }
            g[i*p[j]].v=(g[i].v*g[p[j]].v);
            num[i*p[j]]=p[j];u[i*p[j]]=-u[i];
        }
    }
}
int lowbit(int x){return x&(-x);}
void add(int x,int v){
    for(;x<N;x+=lowbit(x)) tr[x]=(tr[x]+v)&mod;
}
int query(int x){
    int re=0;
    for(;x;x-=lowbit(x)) re=(re+tr[x])&mod;
    return re;
}
inline bool cmp(Ask x,Ask y){
    return x.qa<y.qa;
}
inline bool ucmp(Gval x,Gval y){
    return x.v<y.v;
}
void solve(int uid){
    n=a[uid].qn,m=a[uid].qm;
    int Id=a[uid].id;
    if(n>m) swap(n,m);
    while(g[lst].v<=a[uid].qa&&lst<N){
        int i=g[lst].id;
        for(int j=i;j<N;j+=i)
            add(j,(g[lst].v*u[j/i]));
        ++lst;
    }
    for(int i=1,j;i<=n;i=j+1){
        j=min(n/(n/i),m/(m/i));
        int tmp=(n/i)*(m/i)&mod;
        ans[Id]+=tmp*(query(j)-query(i-1))&mod;
        ans[Id]=ans[Id]&mod;
    }
}
signed main(){
    prepare();
    int t=read();
    for(int i=1;i<=t;i++){
        a[i].qn=read(),a[i].qm=read();
        a[i].qa=read();a[i].id=i;
    }
    sort(a+1,a+t+1,cmp);
    sort(g+1,g+N,ucmp);
    for(int i=1;i<=t;i++) solve(i);
    for(int i=1;i<=t;i++) printf("%lld\n",ans[i]&mod);
    return 0;
}

[SDOI2014] number table

Guess you like

Origin www.cnblogs.com/NLDQY/p/12026162.html