• [bzoj3529][Sdoi2014]数表


    来自FallDream的博客,未经允许,请勿转载,谢谢。


    有一张N×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

    T<=20000组数据,n,m<=10^5

    保证n<=m,f(x)表示x的因数和;

    枚举gcd $$Ans=sum_{d=1}^{n}f(d)*sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}sum_{d|i,d|j}mu(d)$$

    把d扔出来$$Ans=sum_{d=1}^{n}f(d)*sum_{k=1}^{lfloorfrac{n}{d} floor}mu(k)*lfloorfrac{n}{kd} floorlfloorfrac{m}{kd} floor$$

    令$T=kd$得到$$Ans=sum_{T=1}^{n}lfloorfrac{n}{T} floorlfloorfrac{m}{T} floorsum_{d|T,f(d)leqslant a}f(d)mu(T/d)$$

    前面那坨东西只有根号种取值,但是后面那东西不好计算,考虑把询问按照a排序之后插入树状数组计算答案。

    复杂度$O(Tsqrt{n}logn)$

    瞎写自然溢出调了半天 最后弃疗了不如取模

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define MN 100000
    #define ll long long
    #define mod 2147483647
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int mu[MN+5],s[MN],m,num=0,Ans[MN+5];
    bool b[MN+5];
    ll ans=0,c[MN+5],sum;
    pair<ll,int> f[MN+5];
    struct ques{
        int n,m,a,id;
        bool operator<(const ques&b)const{return a<b.a;}    
    }q[MN+5];
    
    inline void ins(int x,ll ad){for(;x<=MN;x+=x&(-x)) c[x]+=ad;}
    inline ll query(int x)
    {
        for(sum=0;x;x-=x&(-x)) sum+=c[x];
        return sum;
    }
    void solve(int a)
    {    
        for(int j=f[a].second;j<=MN;j+=f[a].second) 
            ins(j,f[a].first*mu[j/f[a].second]);
    }
    
    int main()
    {
        mu[1]=1;
        for(int i=1;i<=MN;i++)
            for(int j=i;j<=MN;j+=i) 
                f[j].first+=i;
        for(int i=1;i<=MN;i++) f[i].second=i;
        for(int i=2;i<=MN;i++)
        {
            if(!b[i]) s[++num]=i,mu[i]=-1;
            for(int j=1;s[j]*i<=MN;j++)
            {
                b[s[j]*i]=1;
                if(i%s[j]==0)break;
                mu[s[j]*i]=-mu[i];
            }
        }
        sort(f+1,f+MN+1);
        m=read();    
        for(int i=1;i<=m;i++) 
        {
            q[i].n=read(),q[i].m=read();
            if(q[i].n>q[i].m) swap(q[i].n,q[i].m);
            q[i].a=read();q[i].id=i;
        }
        sort(q+1,q+m+1);
        for(int i=1,j=1;i<=m;i++)
        {
            for(;f[j].first<=(ll)q[i].a&&j<=MN;++j) solve(j);ans=0; 
            for(int j=1,last;j<=q[i].n;j=last+1)
            {
                last=min(q[i].m/(q[i].m/j),q[i].n/(q[i].n/j));
                ans+=((1LL*(query(last)-query(j-1))*(q[i].n/j))&mod)*(q[i].m/j);
                ans&=mod;
            }
            Ans[q[i].id]=ans;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",Ans[i]);
        return 0;
    }
  • 相关阅读:
    如何保持mysql和redis中数据的一致性?
    秒杀系统设计&测试
    缓存穿透、缓存击穿、缓存雪崩区别和解决方案
    数据库关联子查询和非关联子查询
    mysql中 = 与in区别_浅析mysql中 exists 与 in 的区别,空判断
    mysql关键字执行顺序
    python中字典删除元素
    Python list根据下标插入/删除元素
    nginx504网关超时解决方法
    CDN加速
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj3529.html
Copyright © 2020-2023  润新知