• SDOI2014 数表


    有一个n*m的表格,格子(i,j)中的数w是σ(gcd(i,j))。

    Q组询问,每次给出n,m,a。求表中所有不超过a的w之和。

    题解:

    然后后面的用树状数组动态更新即可。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    #define ll long long
    #define MOD 2147483647
    int pri[N],cnt,mu[N],d[N];
    ll sig[N];
    bool vis[N];
    int K[N];
    bool cmpk(int a,int b)
    {
        return sig[a]<sig[b];
    }
    void get_mu()
    {
        mu[1]=1;
        sig[1]=1;
        for(int i=2;i<=100000;i++)
        {
            if(!vis[i])
            {
                pri[++cnt]=i;
                d[i]=1+i;
                sig[i]=1+i;
                mu[i]=-1;
            }
            for(int j=1;j<=cnt&&i*pri[j]<=100000;j++)
            {
                vis[i*pri[j]]=1;
                if(i%pri[j])
                {
                    mu[i*pri[j]]=-mu[i];
                    d[i*pri[j]]=d[pri[j]];
                    sig[i*pri[j]]=sig[pri[j]]*sig[i];
                }else
                {
                    sig[i*pri[j]]=sig[i]/d[i];
                    d[i*pri[j]]=d[i]*pri[j]+1;
                    sig[i*pri[j]]*=d[i*pri[j]];
                    break;
                }
            }
        }
    }
    struct Ques
    {
        int n,m,a,id;
    }q[20050];
    int ans[20050];
    bool cmp(Ques x,Ques y)
    {
        return x.a<y.a;
    }
    int f[N];
    void up(int x,int d)
    {
        if(!x)return ;
        while(x<=100000)
        {
            f[x]+=d;
            x+=(x&(-x));
        }
    }
    int down(int x)
    {
        if(!x)return 0;
        int ret = 0;
        while(x)
        {
            ret+=f[x];
            x-=(x&(-x));
        }
        return ret;
    }
    int Q;
    int main()
    {
        scanf("%d",&Q);
        get_mu();
        for(int i=1;i<=100000;i++)K[i]=i;
        sort(K+1,K+100001,cmpk);
        for(int i=1;i<=Q;i++)
        {
            scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a);
            if(q[i].n>q[i].m)swap(q[i].n,q[i].m);
            q[i].id=i;
        }
        sort(q+1,q+1+Q,cmp);
        for(int i=1,tl=1;i<=Q;i++)
        {
            while(sig[K[tl]]<=q[i].a&&tl<=100000)
            {
                for(int j=1;K[tl]*j<=100000;j++)
                {
                    up(K[tl]*j,mu[j]*sig[K[tl]]);
                }
                tl++;
            }
            int ret = 0;
            for(int j=1,nxt;j<=q[i].n;j=nxt+1)
            {
                nxt = min(q[i].n/(q[i].n/j),q[i].m/(q[i].m/j));
                ret+=(down(nxt)-down(j-1))*(q[i].n/j)*(q[i].m/j);
            }
            ret&=MOD;
            ans[q[i].id]=ret;
        }
        for(int i=1;i<=Q;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    JUC锁框架_AbstractQueuedSynchronizer详细分析
    npm的镜像替换成淘宝
    MHA+keepalived集群环境搭建
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    链表中倒数第k个结点
    调整数组顺序使奇数位于偶数前面
    数值的整数次方
    二进制中1的个数
    矩形覆盖
    OS之进程管理---多线程模型和线程库(POSIX PTread)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10045985.html
Copyright © 2020-2023  润新知