A. Atsa’s Checkers Board

  • 给定一个 n ∗ m n * m n∗m大小的矩阵,在该矩阵内放置黑色白色的石头,要保证每个 2 ∗ 2 2 * 2 2∗2的矩阵都有两个黑石头和两个白石头,问有多少种摆放方式
  • 可以发现当有两块颜色相同的石头摆放在一起的时候,整个矩阵的摆放方式就确定了
  • 可以发现第一行至少有一对颜色相同石子相连的方案数是 1 < < m − 2 1 << m - 2 1<<m−2
  • 而剩下两种没有颜色相同的石子相连的情况,黑白…和白黑…
  • 取其中一种情况作计算。可以发现当第一行确定为黑白…的时候,第一列的排列方式数就为 1 < < ( n − 1 ) 1 << (n - 1) 1<<(n−1)。同理可得第一行确定为白黑…的时候也为 1 < < ( n − 1 ) 1 << (n - 1) 1<<(n−1),两者总和即为 1 < < n 1 << n 1<<n
  • 因此总情况数就是 ( 1 < < m ) + ( 1 < < n ) − 2 (1 << m) + (1 << n) - 2 (1<<m)+(1<<n)−2
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3200;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
inline ll rd() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
int main() {ll n, m;n = rd();m = rd();if (n < 2 || m < 2) {puts("0");return 0;}printf("%lld\n", (1LL << n) + (1LL << m) - 2);return 0;
}

C. CLETS Patrols

  • 假设一个1*n的矩阵 ( a 1 , a 2 , a 3 . . . a n ) (a_1,a_2,a_3...a_n) (a1​,a2​,a3​...an​) , a i a_i ai​ 表示当前守卫在第 i i i 个点的概率

  • 而输入的 n*n 矩阵表示,明显得到以下关系:
    ( a 1 ′ , a 2 ′ , a 3 ′ , . . . , a n ′ ) = ( a 1 , a 2 , a 3 , . . . , a n ) ∗ 输 入 的 n ∗ n 矩 阵 (a_1',a_2',a_3',...,a_n')=(a_1,a_2,a_3,...,a_n)* 输入的n*n矩阵 (a1′​,a2′​,a3′​,...,an′​)=(a1​,a2​,a3​,...,an​)∗输入的n∗n矩阵

  • 所以直接从原始矩阵 ( 1 , 0 , 0 , 0... , 0 ) ∗ ( n ∗ n ) 矩 阵 m (1,0,0,0...,0)*(n*n)矩阵^m (1,0,0,0...,0)∗(n∗n)矩阵m

  • 跑一个矩阵快速幂即可。

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e7 + 10;
const int INF = 0x3f3f3f3f;
inline ll rd() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
ll gcd(ll x, ll y) {if (y == 0) return x;return gcd(y, x % y);
}
int n, m;
struct matrix {double a[202][202];matrix operator *(const matrix& b) {matrix c;/* for (int k = 1;k <= n;++k) {c.a[1][k] = 0;for (int i = 1;i <= n;++i) {c.a[1][k] += this->a[1][i] * b.a[i][k];}}return c;*/for (int i = 1;i <= n;++i) {for (int j = 1;j <= n;++j) {c.a[i][j] = 0;for (int k = 1;k <= n;++k) {c.a[i][j] += this->a[i][k] * b.a[k][j];}}}return c;}
}mp;
matrix fp(matrix a, int y) {matrix ans = a;while (y) {if (y & 1) ans = ans * a;a = a * a;y >>= 1;}return ans;
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> m;for (int i = 1;i <= n;++i) {for (int j = 1;j <= n;++j) {cin >> mp.a[i][j];}}matrix ans = fp(mp, m - 1);for (int i = 1;i <= n;++i) {cout << setprecision(10) << ans.a[1][i] << '\n';}return 0;
}

D. Determine the Winner Marshaland

  • 有题推得,求的是以下条件:
  • x ≡ p i − 2 ( m o d p i ) x\equiv p_i-2\ (mod\ p_i) x≡pi​−2 (mod pi​)
  • 换过来 x + 2 ≡ p i ≡ 0 ( m o d p i ) x+2\equiv p_i\equiv0\ (mod\ p_i) x+2≡pi​≡0 (mod pi​)
  • 所以就对 x + 2 x+2 x+2 进行质因数分解即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ull, ull> pii;
typedef pair<ll, ll>pll;
template<typename T>
inline void rd(T& x) {int tmp = 1;char c = getchar();x = 0;while (c > '9' || c < '0') {if (c == '-')tmp = -1;c = getchar();}while (c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}x *= tmp;
}
const int N = 1e3 + 10;
const int M = 2e7 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ull seed = 31;
ll gcd(ll x, ll y) {if (y == 0) return x;return gcd(y, x % y);
}int head[N], cntE = 0;
struct edge {int next, to;
}e[M];
void add(int u, int v) {e[cntE].to = v;e[cntE].next = head[u];head[u] = cntE++;
}
int n, m, q;
int prime[N], cnt = 0;
bool isprime[N];
void init() {for (int i = 2; i <= N - 5; ++i) {if (!isprime[i]) prime[++cnt] = i;for (int j = 1; j <= cnt && prime[j] * i <= N - 5; ++j) {isprime[i * prime[j]] = 1;if (i % prime[j] == 0) break;}}
}
int main() {#ifdef _DEBUGFILE* _INPUT = freopen("input.txt", "r", stdin);//    FILE* _OUTPUT = freopen("output.txt", "w", stdout);
#endifint T = 1, cas = 0;rd(T);init();while (T--) {rd(n);n += 2;vector<int>ans;while (!(n & 1)) n >>= 1;for (int i = 2; i <= cnt && prime[i] * prime[i] <= n; ++i) {if (n % prime[i] == 0) {ans.push_back(prime[i]);while (n % prime[i] == 0) n /= prime[i];}}if (n > 1) ans.push_back(n);if (ans.empty()) puts("-1");else {for (int i = 0; i < ans.size(); ++i) {printf("%d%s", ans[i], i == ans.size() - 1 ? "\n" : " ");}}}return 0;
}

E. Enterprise Recognition Program

  • 给定一个树形图代表一个公司的主从结构,并且公司中有 n n n个员工,老板节点编号为 0 0 0,老板不属于员工
  • 操作 m m m次,并且有两种操作
  • 第一种操作是给员工 e e e发 v v v元的奖金
  • 第二种操作是给员工 e e e及其所有上司发 v v v元的奖金
  • 询问 q q q次,并且有两种询问
  • 第一种询问是询问员工 x x x有多少奖金
  • 第二种询问是询问员工 x x x的下属和员工 x x x共有多少奖金
  • 设置一个 e a r n earn earn数组, e a r n [ i ] [ 0 ] earn[i][0] earn[i][0]表示公司用操作一发给员工 i i i的奖金, e a r n [ i ] [ 1 ] earn[i][1] earn[i][1]表示公司用操作二发给员工 i i i的奖金, e a r n [ i ] [ 2 ] earn[i][2] earn[i][2]表示员工 i i i的下属们的总奖金
  • 从老板节点开始往下 d f s dfs dfs,从叶子节点往上累加奖金即可
  • 以下为两个递推公式, u u u为当前员工, v v v为 u u u的下属
  • e a r n [ u ] [ 1 ] + = e a r n [ v ] [ 1 ] ; earn[u][1] += earn[v][1]; earn[u][1]+=earn[v][1];
  • e a r n [ u ] [ 2 ] + = e a r n [ v ] [ 0 ] + e a r n [ v ] [ 1 ] + e a r n [ v ] [ 2 ] ; earn[u][2] += earn[v][0] + earn[v][1] + earn[v][2]; earn[u][2]+=earn[v][0]+earn[v][1]+earn[v][2];
  • 具体逻辑在代码中体现
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define lowbit(x) ((x) & -(x))
#define endl "\n"
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e6 + 10, NN = 2e3 + 10, INF = 0x3f3f3f3f, LEN = 20;
const ll MOD = 1e9 + 7;
const ull seed = 31;
const double pi = acos(-1.0), eps = 1e-8;
inline int read() {int x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
struct Edge {int next, to;
} edge[N];
int num_edge, n, m, q, boss;
int head[N], cha[N];
ll earn[N][3];
void add_edge(int from, int to) {edge[num_edge].next = head[from];edge[num_edge].to = to;head[from] = num_edge++;
}
void init() {memset(head, -1, sizeof head);
}
void dfs(int u) {for (int i = head[u]; i != -1; i = edge[i].next) {int v = edge[i].to;dfs(v);earn[u][1] += earn[v][1];earn[u][2] += earn[v][0] + earn[v][1] + earn[v][2];}
}
int main() {// ios::sync_with_stdio(false);// cin.tie(0);// cout.tie(0);// freopen("input.txt", "r", stdin);// freopen("output.txt", "w", stdout);n = read(), m = read(), q = read();init();for (int i = 1; i <= n; ++i) {int x = read();add_edge(x, i);if (x == 0)boss = i;}for (int i = 1; i <= m; ++i) {int m = read(), e = read(), v = read();earn[e][m - 1] += v;}dfs(boss);while (q--) {int op = read(), x = read();if (op == 1)printf("%lld\n", earn[x][0] + earn[x][1]);elseprintf("%lld\n", earn[x][2] + earn[x][1] + earn[x][0]);}return 0;
}

G. Goombas Colliding

  • 无论怎么撞,最终都会有一辆车子走的是他自己的路程或者别人的路程
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e7 + 10;
const int INF = 0x3f3f3f3f;
inline ll rd() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
ll n, m;
void solve() {scanf("%lld %lld", &m, &n);ll ans = 0;for (int i = 1;i <= n;++i) {ll p, x;scanf("%lld %lld", &p, &x);if (x) ans = max(ans, m - p);else ans = max(ans, p);}printf("%lld\n", ans);
}
int main() {int T = 1;while (T--)solve();return 0;
}

H. Hamsters Training

  • 最后出来的公式是 C 2 n − 1 n C_{2n-1}^n C2n−1n​, 怎么来的真不知道
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ull, ull> pii;
typedef pair<ll, ll>pll;
template<typename T>
inline void rd(T& x) {int tmp = 1;char c = getchar();x = 0;while (c > '9' || c < '0') {if (c == '-')tmp = -1;c = getchar();}while (c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}x *= tmp;
}
const int N = 2e5 + 10;
const int M = 2e7 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ull seed = 31;
ll gcd(ll x, ll y) {if (y == 0) return x;return gcd(y, x % y);
}
int n, m, q;
ll fac[N], ifac[N];
ll fp(ll x, ll y) {ll ans = 1;while (y) {if (y & 1) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}
ll C(int x, int y) {ll ans = fac[x];ll res = ifac[x - y] * ifac[y] % mod;ans = ans * res % mod;return ans;
}
int main() {#ifdef _DEBUGFILE* _INPUT = freopen("input.txt", "r", stdin);//    FILE* _OUTPUT = freopen("output.txt", "w", stdout);
#endifint T = 1, cas = 0;rd(T);fac[0] = 1;for (int i = 1; i <= N - 10; ++i) fac[i] = fac[i - 1] * i % mod;ifac[N - 10] = fp(fac[N - 10], mod - 2);for (int i = N - 10; i > 0; --i) ifac[i - 1] = ifac[i] * i % mod;while (T--) {rd(n);ll ans = C(2 * n - 1, n);printf("%lld\n", ans);}return 0;
}

J. Just Turn the Wheels!

  • 根据题目意思,首先车轮滚动的距离要大于 s s s ,所以一个首先满足的 t u r n s turns turns 是 s c ∗ 360 30 \frac{s}{c}*\frac{360}{30} cs​∗30360​

  • 剩下的 s 1 = s % c s1=s\%c s1=s%c 的路程:需要满足在 t u r n s turns turns 的情况下还要让两个车轮的边同时平行于地面

  • 首先去求共同转动的角度 α \alpha α 能够两车轮的边同时平行于地面: α = 360 ° / g c d ( f , b ) \alpha=360°/gcd(f,b) α=360°/gcd(f,b) , f , b f,b f,b 为输入的车轮顶点数

  • 随后求 α \alpha α 和 t u r n s turns turns 的最小公倍数 ,即 θ = l c m ( α , 30 ° ) \theta=lcm(\alpha,30°) θ=lcm(α,30°)

  • 对于 s % c s\%c s%c 需要的角度是 β = ⌈ ( s % c ) / c 360 ° ⌉ \beta=\lceil(s\%c)/\ \frac{c}{360°}\rceil β=⌈(s%c)/ 360°c​⌉

  • 所以最后 s % c s\%c s%c 需要的 t u r n s turns turns 是 ⌈ β θ ⌉ / 30 ° \lceil \frac{\beta}{\theta} \rceil /30° ⌈θβ​⌉/30°

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3200;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
inline ll rd() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
int sgn(double x) {if (fabs(x) < eps)return 0;return x < 0 ? -1 : 1;
}
ll gcd(ll x, ll y) {if (!y) return x;return gcd(y, x % y);
}
ll c, f, b, s;
int main() {int T;scanf("%d", &T);while (T--) {scanf("%lld %lld %lld %lld", &c, &f, &b, &s);ll ans = 12LL * (s / c);s %= c;ll tmp1 = gcd(f, b);ll t = gcd(360, tmp1);ll x = 1LL * 360 / t;ll y = 30 ;ll tmp2 = x * y / gcd(x, y);ll res = (s * 360 / c);if (s * 360 % c != 0) ++res;res = res / tmp2 + (res % tmp2 != 0);res = res * tmp2 / 30;ans += res;printf("%lld\n", ans);}
}

K. Kitchen Waste

  • 有 n n n个面包, m m m口锅,每口锅中都装了一定体积的汤,要将汤淋在面包上,面包也有体积,一体积汤能淋一体积面包
  • 一次淋面包的操作必须要将整个面包都淋上汤,若锅中剩余汤的体积不足以将整个面包都淋上,则将这个锅中的汤都倒掉
  • 签到题,根据题意直接模拟即可
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e7 + 10;
const int INF = 0x3f3f3f3f;
inline ll read() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
int n, m;
int a[N], b[N];
int main() {n = read();m = read();for (int i = 1; i <= n; ++i) a[i] = read();for (int i = 1; i <= m; ++i)b[i] = read();int pos = 1;for (int i = 1; i <= m; ++i) {while (b[i] >= a[pos]) {b[i] -= a[pos];++pos;if (pos > n)break;}if (pos > n)break;}int ans = 0;for (int i = 1; i <= m; ++i)ans += b[i];printf("%d\n", ans);return 0;
}

L. Lets Count Factors

  • 题意很明确,求 A , B A,B A,B 的共同质因数
  • 这题稍有不慎就会超时,下欧拉筛的范围控制到 1 0 7 \sqrt{10^7} 107 ​ 就可以了
  • 对于共同质因数的标记,使用 u n o r d e r e d _ m a p unordered\_map unordered_map 就万无一失了
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3200;
const int INF = 0x3f3f3f3f;
inline ll rd() {ll x = 0, f = 1;char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}return x * f;
}
int cnt;
int vis[N], pri[N];
void Euler(int n) {for (int i = 2; i <= n; i++) {if (!vis[i])pri[++cnt] = i;for (int j = 1; j <= cnt; j++) {if (i * pri[j] > n)break;vis[i * pri[j]] = true;if (i % pri[j] == 0)break;}}
}
unordered_map<int, bool>visn;
void cal(int x) {for (int i = 1;i <= cnt;++i) {if (x % pri[i] == 0) {visn[pri[i]] = 1;while (x % pri[i] == 0) x /= pri[i];}}if (x > 1) visn[x] = 1;
}
void solve() {int a = (int)rd(), b = (int)rd();visn.clear();cal(a);cal(b);printf("%d\n", visn.size());
}
int main() {int T = (int)rd();Euler(N);while (T--)solve();return 0;
}

2020-2021 ICPC - Gran Premio de Mexico - Repechaje相关推荐

  1. 2021 ICPC Gran Premio de Mexico 1ra Fecha

    C.Cypher Decypher 题意 找 [ i , j ] [i,j] [i,j]区间中有多少个质数 思路 数据范围为 1 ≤ i ≤ j ≤ 1 0 6 1\le i\le j\le 10^6 ...

  2. 2022 ICPC Gran Premio de Mexico Repechaje 题解

    目录 A. Average Walk(签到) 题意: 思路: 代码: C. Company Layoffs(签到) 题意: 思路: 代码: D. Denji1(模拟/二分) 思路: 代码: K. Ke ...

  3. 【2021 ICPC Gran Premio de Mexico 2da Fecha F】Flipped Factorization 题解

    题目大意   设 x x x 的质因数分解为 p 1 c 1 p 2 c 2 ⋯ p m c m p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m} p1c1​​p2c2​​⋯pmc ...

  4. 2021 ICPC Gran Premio de Mexico 2da Fecha(C,D,G,I)

    题目 C. Cut the Deck D. Dislike the Raisins G. Grid of Letters I. Integer Multiplicative Persistence C ...

  5. 2022 ICPC Gran Premio de Mexico 1ra Fecha(一)

    今天大部分时间都花在了上一场沈阳站的L题上了,一个树上背包+容斥原理,看了好久才理解,就不硬敲上了,再想几天在写题解.然后今天自己写了场ICPC墨西哥站的 ICPC Gran Premio de Me ...

  6. 训练记录番外篇(2):2022 ICPC Gran Premio de Mexico 2da Fecha

    2022 ICPC Gran Premio de Mexico 2da Fecha 2022.10.3 之前训得ak场,个人认为很edu. (顺便一提,可能这个训练记录番外系列的比赛都非常edu,十分 ...

  7. 2022 ICPC Gran Premio de Mexico 1ra Fecha 题解

    A 线性基 由于数组异或和固定,因此异或和为奇数的位置可以不用考虑,无论如何分,总是只能有1个为奇数,总贡献不变. 考虑异或和为偶数的位置,利用线性基求其中一部分尽可能大的结果,另一部分结果相同. # ...

  8. 2022 ICPC Gran Premio de Mexico 1ra Fecha (B、D、E、F)

    小技巧: stoi(str,0,2) 将从0开始的二进制串转化为十进制串 不是标准函数,慎用(一般应该没问题吧--) 本次补的题应该都是铜.银牌题,可能欧洲场简单很多 D. Different Pas ...

  9. 2022 ICPC Gran Premio de Mexico 2da Fecha Final standings - K. Krystalova‘s Trivial Problem

    K. Krystalova's Trivial Problem time limit per test1 second memory limit per test256 megabytes input ...

最新文章

  1. 我们要的是一个简单的react-router路由
  2. linux 代码获取当前路径,【linux】shell代码,获取当前路径,创建文件夹
  3. java 随机数生成实现_Java中生成随机数的实现方法总结
  4. js数据结构和算法(8)-图
  5. 2021牛客暑期多校训练营1 G-Game of Swapping Numbers(最优解转化+贪心)
  6. 高效实用Kafka-Kafka是什么
  7. Q117:PBRT-V3反射模型(Reflection Models)笔记
  8. iOS UITextField限制输入字数
  9. java分页数据再次进行分页操作
  10. java将小写金额转换为大写的工具类
  11. Mars-Android开发视频教程(全集)
  12. wordpress后台固定菜单消失不见了怎么办?
  13. android 指纹框架,Android标准化指纹识别框架(只基于api23官方标准)
  14. linux 命令:ps 详解
  15. 真正的Java学习从入门到精通
  16. 秒速五厘米(为情怀而补的题)
  17. torch实现clip by tensor操作
  18. MATLAB中的impixel函数——获取图像像素值
  19. CT时间与当前时间的大小比较
  20. Oracle和Postgre的TRUNC函数

热门文章

  1. Java根据IP地址/掩码位(CIDR)和起始IP-终止IP计算网段(IPV4和IPV6)
  2. 01背包,完全背包,多重背包
  3. Node.js报错:UnhandledPromiseRejectionWarning: Unhandled promise rejection
  4. 1月全球CTF比赛时间汇总来了!
  5. Asciinema - 终端日志记录神器,机器学习开发者的福音
  6. [VCS]Coverage Options Introduction
  7. 基于JAVA宠物托管系统计算机毕业设计源码+系统+lw文档+部署
  8. pion最简单webrtc例子
  9. 基于Element组件下动态生成多级表头以及数据
  10. 【统计学习系列】多元线性回归模型(五)——参数与模型的显著性检验:t检验与F检验