2018 Multi-University Training Contest 7

GuGuFishtion

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

则$f[d]=(n/d)\times (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\n", i, f[i], phi[i], ans);
        }
        printf("%lld\n", 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", 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\n", ans);
        for(int i = 1; i <= k; i++)
        {
            printf("%d%c", v[i], i < k ? ' ' : '\n');
        }
    }
    return 0;
}
Code

 

posted @ 2018-08-15 15:33  卷珠帘  阅读(189)  评论(0编辑  收藏  举报