zoukankan      html  css  js  c++  java
  • 2018 Multi-University Training Contest 7

    GuGuFishtion

    dls真厉害,快速求$sum_{a=1}^n sum_{b=1}^m gcd(a,b) $的个数,我想的方法是根据上节课dls讲的方法,要容过来容过去,这次不用了。

    则$f[d]=(n/d) imes (m/d)$。

    而$g[d]=f[d]-sum_{d|x} g[x]$,从大到小枚举因子就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 50;
    typedef long long ll;
    
    bool flag[maxn]; //标记数组
    ll phi[maxn]; //欧拉函数值
    int prime[maxn]; //同时得到素数筛
    int cnt = 0;
    void Get_phi(int n)
    {
        cnt = 0;
        memset(flag,true,sizeof(flag));
        phi[1] = 1;
        for(int i=2;i<=n;i++)
        {
            if(flag[i]) //素数
            {
                prime[cnt++] = i;
                phi[i] = i-1; //素数的欧拉函数值是i-1
            }
            for(int j=0;j<cnt;j++)
            {
                if(i*prime[j]>n)
                {
                    break;
                }
                flag[i*prime[j]] = false;//素数的倍数不是素数
                if(i%prime[j]==0) //i%mod prime = 0,那么phi(i*p) = p*phi(i)
                {
                    phi[i*prime[j]] = prime[j]*phi[i];
                    break;
                }
                else phi[i*prime[j]] = (prime[j]-1)*phi[i];//i mod prime != 0, 那么 phi(i * prime) == phi(i) * (prime-1)
            }
        }
    }
    int inv[maxn];
    ll f[maxn];
    int main()
    {
        int T; scanf("%d", &T);
        Get_phi(1e6 + 10);
        while(T--)
        {
            int n, m, mod; scanf("%d %d %d", &n, &m, &mod);
            if(n > m) swap(n, m);
            inv[0] = inv[1] = 1;
            for(int i = 2; i <= n; i++)
            {
                inv[i] = (ll)(mod - mod / i) * inv[mod % i] % (ll)mod;
            }
            ll ans = 0;
            for(int i = n; i >= 1; i--) ///枚举 d | (a, b)
            {
                f[i] = (ll)n / i * (m / i);
                for(int j = i + i; j <= n; j += i) ///枚举 能够整除d的
                {
                    f[i] = f[i] - f[j];
                }
                ans = (ans + f[i] * i % mod * inv[phi[i]]) % mod;
                //printf("%d %lld phi = %lld %lld
    ", i, f[i], phi[i], ans);
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    Code

    Swordsman

    读入挂真的吓人,砍掉了$2/3$的时间。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 50;
    
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int _read(){
        char ch=nc();int sum=0;
        while(!(ch>='0'&&ch<='9'))ch=nc();
        while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
        return sum;
    }
    struct node
    {
        int a[6];
        int b[6];
    };
    node cur[maxn];
    struct single
    {
        int val, id;
        friend bool operator < (single A, single B)
        {
            return A.val > B.val;
        }
    };
    
    priority_queue<single> q[6];
    int v[6];
    int main()
    {
        int T; T = _read();
        while(T--)
        {
            int n, k;
            n = _read(), k = _read();
           // printf("%d %d
    ", n, k);
            for(int i = 1; i <= k; i++) v[i] = _read();
            for(int i = 1; i <= k; i++)
            {
                while(!q[i].empty()) q[i].pop();
            }
            for(int i = 1; i <= n; i++)
            {
                for(int j = 1; j <= k; j++) cur[i].a[j] = _read();
                for(int j = 1; j <= k; j++) cur[i].b[j] = _read();
                q[1].push({cur[i].a[1], i});
            }
            int flag = 0;
            int ans = 0;
            while(1)
            {
                flag = 0;
                for(int i = 1; i <= k; i++)
                {
                    if(q[i].empty()) continue;
                    single tmp = q[i].top();
                    if(tmp.val <= v[i])
                    {
                        flag = 1;
                        q[i].pop();
                        if(i == k)
                        {
                            ans++;
                            for(int j = 1; j <= k; j++)
                            {
                                v[j] += cur[tmp.id].b[j];
                            }
                        }
                        else
                        {
    
                            q[i + 1].push({cur[tmp.id].a[i + 1], tmp.id});
                        }
                    }
                }
                if(!flag) break;
            }
            printf("%d
    ", ans);
            for(int i = 1; i <= k; i++)
            {
                printf("%d%c", v[i], i < k ? ' ' : '
    ');
            }
        }
        return 0;
    }
    Code
  • 相关阅读:
    2015 多校联赛 ——HDU5319(模拟)
    FZU 2158
    FZU 2157 树形DP
    dp之背包总结篇
    JavaScript parseInt() 函数
    JavaScript全局属性/函数
    学生面试心得
    ssh整合
    spring08事务
    JavaScript数组方法大全
  • 原文地址:https://www.cnblogs.com/littlepear/p/9472901.html
Copyright © 2011-2022 走看看