A. Shovels and Swords
贪心。每次尽量取较多那一边便可。
写法上能够加速,\((2,1),(1,2)\)这种能够看做\((3,3)\),只取\((1,2)\)这种解个方程便可。
代码以下:
ide
/* * Author: heyuhhh * Created Time: 2020/6/11 22:36:15 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 1e5 + 5; void run() { int a, b; cin >> a >> b; if (a > b) swap(a, b); int x = min(b / 2, min(a, b - a)); b -= 2 * x; a -= x; int ans = x; int c = min(a, b); ans += c / 3 * 2; a -= c / 3 * 3; b -= c / 3 * 3; if (a > b) swap(a, b); for (int i = 3; i >= 0; i--) { if (i <= a && 2 * i <= b) { ans += i; break; } } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); int T; cin >> T; while(T--) run(); return 0; }
B. Shuffle
按题意模拟便可。url
Code/* * Author: heyuhhh * Created Time: 2020/6/11 22:44:42 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define l first #define r second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 1e5 + 5; void run() { int n, m, x; cin >> n >> x >> m; vector <pii> a(m); for (int i = 0; i < m; i++) { int l, r; cin >> l >> r; a[i] = MP(l, r); } int Min = x, Max = x; for (int i = 0; i < m; i++) { if (min(a[i].r, Max) >= max(a[i].l, Min)) { Min = min(a[i].l, Min); Max = max(a[i].r, Max); } } cout << Max - Min + 1 << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); int T; cin >> T; while(T--) run(); return 0; }
C. Palindromic Paths
找出矩阵全部对称的斜线就行。代码中有些细节,边界状况要注意一下。spa
Code/* * Author: heyuhhh * Created Time: 2020/6/11 22:55:58 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 1e5 + 5; void run() { int n, m; cin >> n >> m; vector <vector <int>> a(n, vector <int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> a[i][j]; } } int t = n + m - 1; int d = t / 2; int ans = 0; for (int k = 0; k < d; k++) { vector <vector <int>> cnt(2, vector <int>(2)); int i = 0, j = k; if (j >= m) { i += j - m + 1; j = m - 1; } while (j >= 0 && i < n) { ++cnt[0][a[i][j]]; ++i, --j; } i = n - 1, j = m - 1 - k; if (j < 0) { i += j; j = 0; } while (j < m && i >= 0) { ++cnt[1][a[i][j]]; --i, ++j; } ans += min(cnt[0][0] + cnt[1][0], cnt[0][1] + cnt[1][1]); } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); int T; cin >> T; while(T--) run(); return 0; }
D. Two Divisors
令\(a_i=p_1^{q_1}+p_2^{q_2}+\cdots p_k^{q_k}\)构造\(d_1=p_1^{q_1},d_2=\frac{a_i}{d_1}\)就行。
由于有这个式子:
.net
- 若\(x,y\)互质,则\(gcd(x+y,xy)=1\)。
证实的话视频里面有,主要就是用到两个关于\(gcd\)的性质:code
- \(gcd(a,b)=gcd(a+b,b)\);
- 若\(gcd(a,c)=1\),则\(gcd(a,bc)=gcd(a,b)\)。
代码以下:视频
Code/* * Author: heyuhhh * Created Time: 2020/6/11 23:23:11 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 5e5 + 5, M = 2e7 + 5; int n; int cnt; int p[M]; bool chk[M]; void init() { for(int i = 2; i < M; i++) { if(!chk[i]) p[++cnt] = i; for(int j = 1; j <= cnt && 1ll * i * p[j] < M; j++) { chk[i * p[j]] = 1; if (i % p[j] == 0) { break; } } } } pii ans[N]; void run() { cin >> n; for (int i = 1; i <= n; i++) { int x; cin >> x; int tmp = x; vector <int> v; for (int j = 1; j <= cnt; j++) { if (1ll * p[j] * p[j] > x) { break; } if (x % p[j] == 0) { int t = 1; while (x % p[j] == 0) { x /= p[j]; t *= p[j]; } v.push_back(t); } } if (x > 1) { v.push_back(x); } if (sz(v) < 2) { v = {-1, -1}; } else { v = {v[0], tmp / v[0]}; } ans[i] = MP(v[0], v[1]); } for (int i = 1; i <= n; i++) { cout << ans[i].fi << " \n"[i == n]; } for (int i = 1; i <= n; i++) { cout << ans[i].se << " \n"[i == n]; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); init(); run(); return 0; }
E. Two Arrays
首先判掉不合法的状况,若对于\(a_i=b_k\)且此时\(a_i\)为最后一次出现,若\(min\{a_{i+1},\cdots,a_n\}<a_i\),那么就不合法。注意开头\(a_1,\cdots,a_j,a_j\)为\(b_1\)的最后一次出现这段要特判。
以后对于\(1,...,m-1\)每个区间找到尽可能靠左边的右端点,那么很容易得知右端点的取值范围,只要后面的取值合法就行,以后把全部的这些区间乘起来就行。
上述过程能够二分、单调栈、模拟等多种方法解决。
ip
还有一种比较巧妙的作法,就是维护序列\(a\)的后缀,全部后缀最小值相等的区间自然造成了一段合法的移动区间,咱们对于每一个\(b_i\)把个数乘起来就行。注意一下判断不合法的状况,前面说的在实现过程当中乘起来直接等于\(0\),不用特殊判断;但前面那一段没法肯定,加上\(suf_1\not ={b_1}\)就行,这里大了小了都不知足条件。
细节见代码:
ci
/* * Author: heyuhhh * Created Time: 2020/6/12 9:28:53 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 1e5 + 5, MOD = 998244353; void run() { int n, m; cin >> n >> m; vector <int> a(n), b(m); for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < m; i++) { cin >> b[i]; } vector <int> r(m, -1); for (int i = n - 1, j = m - 1; i >= 0; i--) { if (j >= 0 && a[i] == b[j]) { r[j] = i; --j; } } if (r[0] == -1) { cout << 0 << '\n'; return; } r.push_back(n); for (int i = 0; i < r[0]; i++) { if (a[i] < b[0]) { cout << 0 << '\n'; return; } } for (int j = 0; j < m; j++) { for (int i = r[j] + 1; i < r[j + 1]; i++) { if (a[i] < b[j]) { cout << 0 << '\n'; return; } } } int ans = 1; for (int i = 0; i < m - 1; i++) { int j = r[i + 1]; while (j > r[i] && a[j] >= b[i + 1]) { --j; } ans = 1ll * ans * (r[i + 1] - j) % MOD; } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); run(); return 0; }solution2
/* * Author: heyuhhh * Created Time: 2020/6/12 10:09:52 */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #include <assert.h> #include <functional> #include <numeric> #define MP make_pair #define fi first #define se second #define pb push_back #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << std::endl; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } template <template<typename...> class T, typename t, typename... A> void err(const T <t> &arg, const A&... args) { for (auto &v : arg) std::cout << v << ' '; err(args...); } #else #define dbg(...) #endif using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 1e5 + 5, MOD = 998244353; void run() { int n, m; cin >> n >> m; vector <int> a(n), b(m); for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < m; i++) { cin >> b[i]; } vector <int> suf(n); suf[n - 1] = a[n - 1]; for (int i = n - 2; i >= 0; i--) { suf[i] = min(a[i], suf[i + 1]); } if (suf[0] != b[0]) { cout << 0 << '\n'; return; } map <int, int> mp; for (int i = 0; i < n; i++) { ++mp[suf[i]]; } int ans = 1; for (int i = 1; i < m; i++) { ans = 1ll * ans * mp[b[i]] % MOD; } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); run(); return 0; }