Codeforces Round #589 (Div. 2)

目录

  • Contest Info
  • Solutions
    • A. Distinct Digits
    • B. Filling the Grid
    • C. Primes and Multiplication
    • D. Complete Tripartite
    • E. Another Filling the Grid

Contest Info



Practice Link

Solved A B C D E F
5/6 O O O O ? -
  • O 在比赛中通过
  • ? 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Distinct Digits

签到。

B. Filling the Grid

签到。

C. Primes and Multiplication

题意:
定义\(prime(x)\)为\(x\)的所有质因子构成的集合。
定义\(g(x, p)\)为最大的\(p^k\)满足\(p^k \;|\; x\),
定义\(f(x, y)\)为:
\[
\begin{eqnarray*}
\prod\limits_{p \in prime(x)} g(y, p)
\end{eqnarray*}
\]

现在给出\(x, n\),要求计算:
\[
\prod\limits_{i = 1}^n f(x, i) \bmod (10^9 + 7)
\]

思路:
枚举\(x\)的每个质因子,再从高到低枚举每个质因子的幂次,考虑对于一个质因子\(p\),用\(f[i]\)表示\([1, n]\)中有多少个\(p^i\)的倍数,且不是\(p^j (j > i)\)的倍数,那么个数是\(\left\lfloor n / p^i \right\rfloor - \left\lfloor n / p^{i + 1} \right\rfloor\)

代码:

view code

#include <bits/stdc++.h>
using namespace std;
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using ll = long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
using VI = vector <int>;
using VL = vector <ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
template <class T> inline void out(T s) { cout << s << "\n"; }
template <class T> inline void out(vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 1e5 + 10;
ll x, n, bit[110];
inline ll ceil(ll x, ll y) {
    return (x + y - 1) / y;
}
void run() {
    vector <int> fac;
    for (ll i = 2; i * i <= x; ++i) {
        if (x % i == 0) fac.push_back(i);
        while (x % i == 0) x /= i;
    }
    if (x != 1) fac.push_back(x);
    ll res = 1;
    for (auto &it : fac) {
        if (it > n) continue;
        int k = 1; bit[1] = it;
        for (int i = 2; ; ++i) {
            if (bit[i - 1] > ceil(n, it)) {
                k = i - 1;
                break;
            }
            bit[i] = bit[i - 1] * it;
        }
        ll tot = 0;
        for (int i = k; i >= 1; --i) {
            ll p = n / bit[i];
            p -= tot;
            res = res * qpow(bit[i] % mod, p % (mod - 1)) % mod;
            tot += p;
        }
    }
    out(res);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    while (cin >> x >> n) run();
    return 0;
}

D. Complete Tripartite

题意:
现在给出一张\(n\)个点\(m\)条边的无向图,没有自环和重边, 问能否将点分成三个集合,使得集合内部的点之间没有边相连,但任意两个点(他们分属不同的集合)有边相连。
如果可以,输出方案。

思路:
考虑同一点集里所有的点连出去的边都是相同的,那么根据这个\(Hash\),如果刚好有三种\(Hash\)值,那么按\(Hash\)值分类即可

代码:

view code

#include <bits/stdc++.h>
using namespace std;
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
using VI = vector <int>;
using VL = vector <ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
template <class T> inline void out(T s) { cout << s << "\n"; }
template <class T> inline void out(vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 3e5 + 10;
int n, m, ans[N];
mt19937 rnd(time(0));
ull f[N], g[N];
map <ull, vector<int>> mp;
void run() {
    for (int i = 1; i <= n; ++i) f[i] = rnd();
    memset(g, 0, sizeof g);
    mp.clear();
    for (int i = 1, u, v; i <= m; ++i) {
        cin >> u >> v;
        g[u] ^= f[v];
        g[v] ^= f[u];
    }
    for (int i = 1; i <= n; ++i) {
        mp[g[i]].push_back(i);
        if (mp.size() > 3) return out(-1);
    }
    if (mp.size() != 3) return out(-1);
    int cnt = 0;
    for (auto &it : mp) {
        ++cnt;
        for (auto &u : it.second) {
            ans[u] = cnt;
        }
    }
    for (int i = 1; i <= n; ++i)
        cout << ans[i] << " \n"[i == n];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    while (cin >> n >> m) run();
    return 0;
}

E. Another Filling the Grid

题意:
给出一个\(n \cdot n\)的矩形,每个位置可以填\([1, k]\)。
现在要求每一行至少有一个\(1\),每一列至少有一个\(1\),问填数的方案数。

思路一:
考虑\(f[i][j]\)表示考虑前\(i\)行有\(j\)列有\(1\),转移的时候注意每一行至少有一个\(1\)。
时间复杂度\(O(n^3)\)

代码一:

view code

#include <bits/stdc++.h>
using namespace std;
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using ll = long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
using VI = vector <int>;
using VL = vector <ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
template <class T> inline void out(T s) { cout << s << "\n"; }
template <class T> inline void out(vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 300 + 10;
int n, K; ll f[N][N], C[N][N];
void run() {
    if (n == 1 || K == 1) return out(1);
    memset(f, 0, sizeof f);
    for (int i = 1; i <= n; ++i) {
        f[1][i] = C[n][i] * qpow(K - 1, n - i) % mod;
    }
    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            ll p = qpow(K, j);
            for (int k = j; k <= n; ++k) {
                if (k == j) chadd(f[i][k], f[i - 1][j] * (p + mod - qpow(K - 1, j)) % mod * qpow(K - 1, n - k) % mod);
                else chadd(f[i][k], f[i - 1][j] * p % mod * C[n - j][k - j] % mod * qpow(K - 1, n - k) % mod);
            }
        }
    }
    out(f[n][n]);
}

int main() {
    memset(C, 0, sizeof C);
    C[0][0] = 1;
    for (int i = 1; i < N; ++i) {
        C[i][0] = C[i][i] = 1;
        for (int j = 1; j < i; ++j)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    }
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    while (cin >> n >> K) run();
    return 0;
}

思路二:
考虑枚举有\(i\)行\(j\)列没有\(1\),然后根据\((i + j)\)的奇偶性容斥。
时间复杂度\(O(n^2)\)

代码二:

view code

#include <bits/stdc++.h>
using namespace std;
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using ll = long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
using VI = vector <int>;
using VL = vector <ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
template <class T> inline void out(T s) { cout << s << "\n"; }
template <class T> inline void out(vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 300 + 10;
int n, K; ll f[N][N], C[N][N];
void run() {
    if (n == 1 || K == 1) return out(1);
    ll ans = 0;
    //枚举有i行,j列没有1,容斥
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j <= n; ++j) {
            ll ch = i * n + j * n - i * j;
            ll ex = n * n - ch;
            ll now = C[n][i] * C[n][j] % mod * qpow(K - 1, ch) % mod * qpow(K, ex) % mod;
            if ((i + j) & 1) chadd(ans, mod - now);
            else chadd(ans, now);
        }
    }
    out(ans);
}

int main() {
    C[0][0] = 1;
    for (int i = 1; i < N; ++i) {
        C[i][0] = C[i][i] = 1;
        for (int j = 1; j < i; ++j)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    }
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    while (cin >> n >> K) run();
    return 0;
}

思路三:
考虑枚举有\(i\)行没有\(1\),那么保证每一列都至少有一个\(1\),那么答案就是:
\[
\begin{eqnarray*}
\sum\limits_{i = 0}^{n - 1} (-1)^i{n \choose i}(k - 1)^{in}f^n(n - i)
\end{eqnarray*}
\]
其中\(f[i]\)表示有\(i\)个数,至少有一个\(1\)的方案数,显然有:
\[
\begin{eqnarray*}
f[i] = k^{i} - (k - 1)^i
\end{eqnarray*}
\]
时间复杂度\(O(nlogk)\)

代码三:

view code

#include <bits/stdc++.h>
using namespace std;
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using ll = long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
using VI = vector <int>;
using VL = vector <ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
template <class T> inline void out(T s) { cout << s << "\n"; }
template <class T> inline void out(vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 300 + 10;
int n, K; ll f[N], C[N][N];
void run() {
    if (n == 1 || K == 1) return out(1);
    ll ans = 0;
    //枚举有i行没有1,然后保证每列至少有一个1,容斥
    for (int i = 0; i < n; ++i) {
        ll f = (qpow(K, n - i) - qpow(K - 1, n - i) + mod) % mod;
        ll now = qpow(f, n) * C[n][i] % mod * qpow(K - 1, n * i) % mod;
        if (i & 1) chadd(ans, -now);
        else chadd(ans, now);
    }
    out(ans);
}

int main() {
    C[0][0] = 1;
    for (int i = 1; i < N; ++i) {
        C[i][0] = C[i][i] = 1;
        for (int j = 1; j < i; ++j)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    }
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    while (cin >> n >> K) run();
    return 0;
}

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

时间: 2024-10-10 00:41:16

Codeforces Round #589 (Div. 2)的相关文章

Codeforces Round #589 (Div. 2)-E. Another Filling the Grid-容斥定理

Codeforces Round #589 (Div. 2)-E. Another Filling the Grid-容斥定理 [Problem Description] 在\(n\times n\)的格子中填入\([1,k]\)之间的数字,并且保证每一行至少有一个\(1\),每一列至少有一个\(1\),问有多少种满足条件的填充方案. [Solution] 令\(R[i]\)表示为第\(i\)行至少有一个\(1\)的方案数,\(C[i]\)表示第\(i\)列至少有一个\(1\)的方案数.则题目要

Codeforces Round #589 (Div. 2) B——B. Filling the Grid

Suppose there is a h×wh×w grid consisting of empty or full cells. Let's make some definitions: riri is the number of consecutive full cells connected to the left side in the ii-th row (1≤i≤h1≤i≤h). In particular, ri=0ri=0 if the leftmost cell of the 

Codeforces Round 589 (Div. 2) 题解

Is that a kind of fetishism? No, he is objectively a god. 见识了一把 Mcdic 究竟出题有多神. (虽然感觉还是吹过头了) 开了场 Virtual 玩. 开场先秒了 AB.C 居然差点没做出来,有点耻辱. 开 D.怎么不会--Div. 2 的 D 都能卡住我,我心态崩了. 调到 E. woc 这不是 sb 题吗-- 回来肝 D.想了想口胡出来了,然而心态已经崩了,用了很长很长时间才打出来. 最后只剩 20min 时开 F.这--辣鸡三合

Codeforces Round #589 (Div. 2) (e、f没写)

https://codeforces.com/contest/1228/problem/A A. Distinct Digits 超级简单嘻嘻,给你一个l和r然后寻找一个数,这个数要满足的条件是它的每一位的数字不相同,找出满足要求的最小的那个数输出,没有找到就输出-1: 1 #include<bits/stdc++.h> 2 using namespace std; 3 bool check(int n){ 4 int vis[15]={0}; 5 while(n){ 6 if(!vis[n%

Codeforces Round #589 (Div. 2) A. Distinct Digits

链接: https://codeforces.com/contest/1228/problem/A 题意: You have two integers l and r. Find an integer x which satisfies the conditions below: l≤x≤r. All digits of x are different. If there are multiple answers, print any of them. 思路: 水题. 代码: #include

Codeforces Round #589 (Div. 2) - A

题目大意:给定一个闭区间,问这个区间内有没有满足各数位数字不相等的数,有的话输出任意一个,没有的话输出 -1. #include <bits/stdc++.h> #include <bitset> using namespace std; #define mp(x, y) make_pair(x,y) #define mset(a, n) memset(a, n, sizeof(a)) #define forn(i, n) for (int i = 0; i < (n); i

Codeforces Round #589 (Div. 2) - C

题目大意:$prime(x)$ 代表 $x$ 的质因数的集合. $g(x, p)$ 代表 $p^k$ 的最大值, $k$ 为整数,并且 $x$ 可以被 $p^k$ 整除. $f(x, p)$ 代表 对于 $prime(x)$ 中的每一个 $x$ 的 $g(x, p)$ 值. 现在给定 $x, n$ 求 $f(x, 1) * f(x, 2) * ... *f(x, n) mod (10^9 + 7)$ 的值. 思路:对于 $x$ 进行质因数分解,分别考虑每一个 $prime(x)$ 对答案做出的贡

Codeforces Round #589 (Div. 2) - B

题目大意:给定一个 $h$ 行, $w$ 列的矩形,接下来一行 $h$ 个数字, $hi$ 代表第 $i$ 行从左到右有连续的 $hi$ 个染成黑色的方块,列同理,然后问满足条件的矩形的个数(% 1e9 + 7). 比赛写的时候第一次挂掉了,因为判断原条件不成立的代码写挂了= = ,不知道自己当时在想什么. 我在处理数据时,开了两个数组,分别记录行与列的染色情况. forab(i, 1, h) { cin >> r[i]; forab(k, 1, r[i]) G[i][k] = 1, R[i]

Codeforces Round #589 div.2 C,D

感觉这一场的复杂度非常的玄学... 也可能是我偷懒太长时间变菜了QAQ. C 题意: 给出\(x,n\),求x质因子的从1到n的g(i,p)的连乘 思路: 求出x的每个质因子,直接连乘到n计算即可. #include<bits/stdc++.h> #define ll long long using namespace std; typedef pair<int,int> pii; typedef vector<int> VI; vector<int> pr