2019 ICPC Asia Yinchuan Regional

时间:2019-11-30
本文章向大家介绍2019 ICPC Asia Yinchuan Regional,主要包括2019 ICPC Asia Yinchuan Regional使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Contest Info


Practice Link

Solved A B C D E F G H I J K L M N
9/14 O O - O - O O O O - O - - O
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Girls Band Party

B. So Easy

题意:
给出一个\(n \cdot n\)的矩形,这个矩形\(a_{i, j}\)的初始值为\(0\),它每次能够选择一行或者一列加上\(1\),现在遮住某个位置的数,让你还原这个数。

思路:
考虑倒退操作,不考虑遮住的那个数,然后枚举每行,每列,每次选择行最小,列最小将整行整列减去即可还原出那个数。

代码:


view code

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, a[N][N];

int main() {
    while (scanf("%d", &n) != EOF) {
        int x = -1, y = -1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                scanf("%d", &a[i][j]);
                if (a[i][j] == -1) {
                    x = i, y = j;
                    a[i][j] = 0;
                }
            }
        }
        for (int i = 1; i <= n; ++i) {
            int Min = 1e9;
            for (int j = 1; j <= n; ++j) {
                if (x == i && y == j) continue;
                Min = min(Min, a[i][j]);
            }
            for (int j = 1; j <= n; ++j) {
                a[i][j] -= Min;
            }
        }
        for (int j = 1; j <= n; ++j) {
            int Min = 1e9;
            for (int i = 1; i <= n; ++i) {
                if (x == i && y == j) continue;
                Min = min(Min, a[i][j]);
            }
            for (int i = 1; i <= n; ++i) {
                a[i][j] -= Min;
            }
        }
        printf("%d\n", -a[x][y]);
    }
    return 0;
}

D. Easy Problem

题意:
定义一个序列\((a_1, a_2, \cdots, a_n)\)是一个\((n, m, d)-good\)当且仅当\(1 \leq a_i \leq m(1 \leq i \leq n)\)并且\(gcd(a_1, a_2, \cdots, a_n) = d\)
\(f(a, k) = (a_1a_2\cdotsa_n)^k\),现在给出\(n, m, d, k\),让你求所有合法的\((n, m, d)-good\)的序列\(a\)\(f(a, k)\)

思路:
题目要求的东西等价于:
\[ \begin{eqnarray*} f(d) = \sum\limits_{a_1 = 1}^m \sum\limits_{a_2 = 1}^m \cdots \sum\limits_{a_n = 1}^m [gcd(a_1, a_2, \cdots, a_n) = d](a_1a_2\cdotsa_n)^k \end{eqnarray*} \]
那么我们令:
\[ \begin{eqnarray*} g(d) = \sum\limits_{a_1 = 1}^m \sum\limits_{a_2 = 1}^m \cdots \sum\limits_{a_n = 1}^m [d | gcd(a_1, a_2, \cdots, a_n)](a_1a_2\cdotsa_n)^k \end{eqnarray*} \]
显然有:
\[ \begin{eqnarray*} g(d) = (\sum\limits_{d\;|\;i} i^k)^n \end{eqnarray*} \]
莫比乌斯反演有:
\[ \begin{eqnarray*} f(d) &=& \sum\limits_{d\;|\;i} \mu(\frac{i}{d})g(i) \\ &=& \sum\limits_{d\;|\;i} \mu(\frac{i}{d}) (\sum\limits_{i\;|\;j} j^k)^n \end{eqnarray*} \]
所以:
\[ f(d) &=& \sum\limits_{i = 1}^{\left\lfloor m/d \right\rfloor} \mu(i) (\sum\limits_{j\;|\;id} j^k)^n \]

代码:


view code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10, mod = 59964251;
int pri[N], check[N], mu[N], n, m, d, K, phi; 
char s[N]; 
void sieve() {
    memset(check, 0, sizeof check);
    *pri = 0;
    mu[1] = 1;
    for (int i = 2; i < N; ++i) {
        if (check[i] == 0) {
            pri[++*pri] = i;
            mu[i] = -1;
        }
        for (int j = 1; j <= *pri; ++j) {
            if (i * pri[j] >= N) break;
            check[i * pri[j]] = 1;
            if (i % pri[j] == 0) {
                mu[i * pri[j]] = 0;
                break;
            } else {
                mu[i * pri[j]] = -mu[i];
            }
        }
    }
}

int eular(int n) {
    int ans = n;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            ans -= ans / i;
            while (n % i == 0) 
                n /= i;
        }
    }
    if (n > 1) ans -= ans / n;
    return ans;
}

ll gcd(ll a, ll b) {
    return b ? gcd(b, a % b) : a;
}

ll qmod(ll base, ll n) {
    ll res = 1;
    while (n) {
        if (n & 1) res = res * base % mod;
        base = base * base % mod;
        n >>= 1;
    }
    return res;
}

int getMod(int mod) {
    int res = 0;
    for (int i = 1; s[i]; ++i) {
        res = (res * 10 + s[i] - '0') % mod;
    }
    return res;
}

int main() {
    phi = eular(mod);
    sieve();    
//  cout << phi << endl;
    int _T; scanf("%d", &_T);
    while (_T--) {
        scanf("%s%d%d%d", s + 1, &m, &d, &K);
        int len = strlen(s + 1);
        if (len <= 9) {
            n = 0;
            for (int i = 1; s[i]; ++i) {
                n = n * 10 + s[i] - '0';
            }
        } else {
            n = getMod(phi);
            if (getMod(643) == 0 || getMod(93257) == 0) {
                n += phi;
            }
        }
        ll res = 0;
        for (int i = 1; i <= m / d; ++i) {
            int base = 0;
            for (int j = i * d; j <= m; j += i * d) {
                base += qmod(j, K);
                base %= mod;
            }
            res += 1ll * mu[i] * qmod(base, n) % mod;
            res = (res + mod) % mod;
        }
        printf("%lld\n", res);
    }
    return 0;
}

题意:

思路:

代码:


view code

题意:

思路:

代码:


view code

题意:

思路:

代码:


view code

题意:

思路:

代码:


view code

题意:

思路:

代码:


view code

题意:

思路:

代码:


view code

原文地址:https://www.cnblogs.com/Dup4/p/11963769.html