题解

1 条题解

  • 0
    @ 2017-11-07 17:24:05
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    typedef long long LL;
    
    const int N=4000005;
    const int MOD=1000000007;
    
    int n,m,phi[N],tot,prime[N/10],f[N],w[N],tag[N],block,val[N];
    bool not_prime[N];
    
    void prework(int n)
    {
        phi[1]=1;
        for (int i=2;i<=n;i++)
        {
            if (!not_prime[i]) prime[++tot]=i,phi[i]=i-1;
            for (int j=1;j<=tot&&i*prime[j]<=n;j++)
            {
                not_prime[i*prime[j]]=1;
                if (i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
        for (int i=1;i<=n;i++) f[i]=(f[i-1]+(LL)i*i%MOD*phi[i]%MOD)%MOD;
        for (int i=1;i<=n;i++) w[i]=(w[i-1]+(LL)i*i%MOD)%MOD,val[i]=(LL)i*i%MOD;
    }
    
    int gcd(int x,int y)
    {
        if (!y) return x;
        else return gcd(y,x%y);
    }
    
    int solve(int n)
    {
        int ans=0;
        for (int i=1,last;i<=n;i=last+1)
        {
            last=n/(n/i);
            ans=(ans+(LL)(w[last]+tag[(last+block-1)/block]-w[i-1]-tag[(i+block-2)/block])*f[n/i]%MOD)%MOD;
        }
        return (ans+MOD)%MOD;
    }
    
    int main()
    {
        scanf("%d%d",&m,&n);
        block=sqrt(n);
        prework(n);
        while (m--)
        {
            int a,b,y;LL x;
            scanf("%d%d%lld%d",&a,&b,&x,&y);
            int c=gcd(a,b),v=(LL)x/(a/c)/(b/c)%MOD,u=val[c];val[c]=v;
            for (int i=c;i<=(c+block-1)/block*block;i++) w[i]=(w[i]+v-u)%MOD,w[i]=(w[i]+MOD)%MOD;
            for (int i=(c+block-1)/block+1;i<=(n+block-1)/block;i++) tag[i]=(tag[i]+v-u)%MOD,tag[i]=(tag[i]+MOD)%MOD;
            printf("%d\n",solve(y));
        }
    }
    
  • 1

信息

难度
9
分类
(无)
标签
(无)
递交数
1
已通过
1
通过率
100%
上传者