2020-2021 ICPC - Gran Premio de Mexico - Repechaje
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相关推荐
- 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 ...
- 2022 ICPC Gran Premio de Mexico Repechaje 题解
目录 A. Average Walk(签到) 题意: 思路: 代码: C. Company Layoffs(签到) 题意: 思路: 代码: D. Denji1(模拟/二分) 思路: 代码: K. Ke ...
- 【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} p1c1p2c2⋯pmc ...
- 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 ...
- 2022 ICPC Gran Premio de Mexico 1ra Fecha(一)
今天大部分时间都花在了上一场沈阳站的L题上了,一个树上背包+容斥原理,看了好久才理解,就不硬敲上了,再想几天在写题解.然后今天自己写了场ICPC墨西哥站的 ICPC Gran Premio de Me ...
- 训练记录番外篇(2):2022 ICPC Gran Premio de Mexico 2da Fecha
2022 ICPC Gran Premio de Mexico 2da Fecha 2022.10.3 之前训得ak场,个人认为很edu. (顺便一提,可能这个训练记录番外系列的比赛都非常edu,十分 ...
- 2022 ICPC Gran Premio de Mexico 1ra Fecha 题解
A 线性基 由于数组异或和固定,因此异或和为奇数的位置可以不用考虑,无论如何分,总是只能有1个为奇数,总贡献不变. 考虑异或和为偶数的位置,利用线性基求其中一部分尽可能大的结果,另一部分结果相同. # ...
- 2022 ICPC Gran Premio de Mexico 1ra Fecha (B、D、E、F)
小技巧: stoi(str,0,2) 将从0开始的二进制串转化为十进制串 不是标准函数,慎用(一般应该没问题吧--) 本次补的题应该都是铜.银牌题,可能欧洲场简单很多 D. Different Pas ...
- 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 ...
最新文章
- 我们要的是一个简单的react-router路由
- linux 代码获取当前路径,【linux】shell代码,获取当前路径,创建文件夹
- java 随机数生成实现_Java中生成随机数的实现方法总结
- js数据结构和算法(8)-图
- 2021牛客暑期多校训练营1 G-Game of Swapping Numbers(最优解转化+贪心)
- 高效实用Kafka-Kafka是什么
- Q117:PBRT-V3反射模型(Reflection Models)笔记
- iOS UITextField限制输入字数
- java分页数据再次进行分页操作
- java将小写金额转换为大写的工具类
- Mars-Android开发视频教程(全集)
- wordpress后台固定菜单消失不见了怎么办?
- android 指纹框架,Android标准化指纹识别框架(只基于api23官方标准)
- linux 命令:ps 详解
- 真正的Java学习从入门到精通
- 秒速五厘米(为情怀而补的题)
- torch实现clip by tensor操作
- MATLAB中的impixel函数——获取图像像素值
- CT时间与当前时间的大小比较
- Oracle和Postgre的TRUNC函数
热门文章
- Java根据IP地址/掩码位(CIDR)和起始IP-终止IP计算网段(IPV4和IPV6)
- 01背包,完全背包,多重背包
- Node.js报错:UnhandledPromiseRejectionWarning: Unhandled promise rejection
- 1月全球CTF比赛时间汇总来了!
- Asciinema - 终端日志记录神器,机器学习开发者的福音
- [VCS]Coverage Options Introduction
- 基于JAVA宠物托管系统计算机毕业设计源码+系统+lw文档+部署
- pion最简单webrtc例子
- 基于Element组件下动态生成多级表头以及数据
- 【统计学习系列】多元线性回归模型(五)——参数与模型的显著性检验:t检验与F检验