240424刷题题解
Walk on Matrix
CodeForces - 1332D
思路
构造题,每个 d p i , j dp_{i,j} dpi,j都是由其左上方向中的按位与最大值决定的。
我们需要从使得贪心解与正确解的差值为 k k k。
为了方便获得 k k k,可以考虑构造一个贪心解为 0 0 0的矩阵。
写出例二的二进制表示
观察可知左边界上的数只能由其上方的数决定(上边界同理)。
由按位与的性质可知, 2 n − 1 2^{n}-1 2n−1即 1111111 … 1111111\ldots 1111111…这种形式的数按位与任意数 x x x得到的数任然是 x x x本身。
利用这两条性质,我们可以利用左边界或者上边界来传递需要的数。
由按位与的性质可知,如果 2 n > x 2^n>x 2n>x,那么 2 n & x = 0 2^n\&x=0 2n&x=0。
利用条性质,我们可以构造出如下矩阵,利用上边界和右边界(或左边界和下边界)以及 2 n + 1 − 1 2^{n+1}-1 2n+1−1传递 k k k,利用 2 n 2^n 2n来截断边界上的正确解。
题解
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>#define endl '\n'#define ft first
#define sd second#define yes cout << "yes\n"
#define no cout << "no\n"#define Yes cout << "Yes\n"
#define No cout << "No\n"#define YES cout << "YES\n"
#define NO cout << "NO\n"#define pb push_back
#define eb emplace_back#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"// 红色
#define DEBUG1(x) \RED; \cout << #x << " : " << x << endl; \RESET;// 绿色
#define DEBUG2(x) \GREEN; \cout << #x << " : " << x << endl; \RESET;// 蓝色
#define DEBUG3(x) \BLUE; \cout << #x << " : " << x << endl; \RESET;// 品红
#define DEBUG4(x) \MAGENTA; \cout << #x << " : " << x << endl; \RESET;// 青色
#define DEBUG5(x) \CYAN; \cout << #x << " : " << x << endl; \RESET;// 黄色
#define DEBUG6(x) \YELLOW; \cout << #x << " : " << x << endl; \RESET;using namespace std;typedef long long ll;
typedef unsigned long long ull;typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;typedef vector<vi> vvi;
typedef vector<vl> vvl;typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;template <typename T>
inline T read()
{T x = 0;int y = 1;char ch = getchar();while (ch > '9' || ch < '0'){if (ch == '-')y = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + (ch ^ 48);ch = getchar();}return x * y;
}template <typename T>
inline void write(T x)
{if (x < 0){putchar('-');x = -x;}if (x >= 10){write(x / 10);}putchar(x % 10 + '0');
}/*#####################################BEGIN#####################################*/void solve()
{int k;cin >> k;cout << 3 << " " << 2 << endl;int t1 = 131072;int t2 = 262143;cout << t2 << " " << k << endl;cout << t1 << " " << t2 << endl;cout << k << " " << k << endl;
}int main()
{ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);int _ = 1;// std::cin >> _;while (_--){solve();}return 0;
}//
Peaceful Rooks
CodeForces - 1411C
图,dfs
思路
仔细思考不难发现,如果以相同行号和列号作为一个节点的编号,那么可以轻易的将点在棋盘上的位置关系转化为图上的边,那么要移动棋子使得棋子的行号和列行相同,则表示为要将我们所建的抽象图的每个点转化为自环。因为同一行和列上不能同时出现两个棋子,即一个点的度数不能大于2。所以如果要把一个环上的所有点的边都变成自环,就需要额外一个点辅助存放拆下来的第一条边,所以需要 n + 1 n+1 n+1次操作,如果把一条链上的所有点的边变成自环,只需 n n n次操作。
所以, 总操作数 = 环上的点数 + 1 + 链上的点数 总操作数=环上的点数+1+链上的点数 总操作数=环上的点数+1+链上的点数
只需要用并查集查一下抽象图上的环就行了。
题解
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>#define endl '\n'#define ft first
#define sd second#define yes cout << "yes\n"
#define no cout << "no\n"#define Yes cout << "Yes\n"
#define No cout << "No\n"#define YES cout << "YES\n"
#define NO cout << "NO\n"#define pb push_back
#define eb emplace_back#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"// 红色
#define DEBUG1(x) \RED; \cout << #x << " : " << x << endl; \RESET;// 绿色
#define DEBUG2(x) \GREEN; \cout << #x << " : " << x << endl; \RESET;// 蓝色
#define DEBUG3(x) \BLUE; \cout << #x << " : " << x << endl; \RESET;// 品红
#define DEBUG4(x) \MAGENTA; \cout << #x << " : " << x << endl; \RESET;// 青色
#define DEBUG5(x) \CYAN; \cout << #x << " : " << x << endl; \RESET;// 黄色
#define DEBUG6(x) \YELLOW; \cout << #x << " : " << x << endl; \RESET;using namespace std;typedef long long ll;
typedef unsigned long long ull;typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;typedef vector<vi> vvi;
typedef vector<vl> vvl;typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;template <typename T>
inline T read()
{T x = 0;int y = 1;char ch = getchar();while (ch > '9' || ch < '0'){if (ch == '-')y = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + (ch ^ 48);ch = getchar();}return x * y;
}template <typename T>
inline void write(T x)
{if (x < 0){putchar('-');x = -x;}if (x >= 10){write(x / 10);}putchar(x % 10 + '0');
}/*#####################################BEGIN#####################################*/const int N = 2e5 + 5;int p[N];int find(int x)
{if (p[x] != x)p[x] = find(p[x]);return p[x];
}void solve()
{int n, m;cin >> n >> m;for (int i = 1; i <= n; i++)p[i] = i;int a, b;int ans = 0;for (int i = 0; i < m; i++){cin >> a >> b;if (a == b)continue;if (find(a) == find(b))ans += 2;else{ans++;p[find(a)] = find(b);}}cout << ans << endl;
}int main()
{ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);int _ = 1;std::cin >> _;while (_--){solve();}return 0;
}// https://codeforces.com/problemset/problem/1411/C
Mathematical Problem
CodeForces - 1916D
思路
对于 n ≤ 3 n\leq3 n≤3来说,答案由样例直接给出了。
所以考虑 n ≥ 5 n\geq5 n≥5的情况。
若 a = b 2 a=b^2 a=b2,则 b × 100 = ( c × 10 ) 2 b\times100=(c\times10)^2 b×100=(c×10)2,所以对于任意 n ≥ 3 n\geq3 n≥3来说,我们都可以由 n − 2 n-2 n−2的方案乘以 100 100 100获得 n − 2 n-2 n−2种方案,所以我们需要只需要 再额外寻找两个方案就行了。
由于 × 100 \times100 ×100使得数集中多了两个 0 0 0,所以需要寻找一种平方数,在非首位插入两个零之后仍为平方数。
观察样例给出的 n n n为 3 3 3的方案: 169 , 196 , 961 169,196,961 169,196,961,尝试插入两个 0 0 0,发现 10609 = 10 3 2 , 90601 = 30 1 2 10609=103^2,90601=301^2 10609=1032,90601=3012。
以此类推,发现 1006009 = 100 3 2 , 9006001 = 300 1 2 1006009=1003^2,9006001=3001^2 1006009=10032,9006001=30012。
所以所需的两个平方数可以通过在 169 169 169和 961 961 961的第 2 2 2位和倒数第 2 2 2位插入 n − 3 2 \frac {n-3}{2} 2n−3个 0 0 0获得。
题解
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>#define endl '\n'#define ft first
#define sd second#define yes cout << "yes\n"
#define no cout << "no\n"#define Yes cout << "Yes\n"
#define No cout << "No\n"#define YES cout << "YES\n"
#define NO cout << "NO\n"#define pb push_back
#define eb emplace_back#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"// 红色
#define DEBUG1(x) \RED; \cout << #x << " : " << x << endl; \RESET;// 绿色
#define DEBUG2(x) \GREEN; \cout << #x << " : " << x << endl; \RESET;// 蓝色
#define DEBUG3(x) \BLUE; \cout << #x << " : " << x << endl; \RESET;// 品红
#define DEBUG4(x) \MAGENTA; \cout << #x << " : " << x << endl; \RESET;// 青色
#define DEBUG5(x) \CYAN; \cout << #x << " : " << x << endl; \RESET;// 黄色
#define DEBUG6(x) \YELLOW; \cout << #x << " : " << x << endl; \RESET;using namespace std;typedef long long ll;
typedef unsigned long long ull;typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;typedef vector<vi> vvi;
typedef vector<vl> vvl;typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;template <typename T>
inline T read()
{T x = 0;int y = 1;char ch = getchar();while (ch > '9' || ch < '0'){if (ch == '-')y = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + (ch ^ 48);ch = getchar();}return x * y;
}template <typename T>
inline void write(T x)
{if (x < 0){putchar('-');x = -x;}if (x >= 10){write(x / 10);}putchar(x % 10 + '0');
}/*#####################################BEGIN#####################################*/
const int N = 105;vs ans[N];
void solve()
{int n;cin >> n;for (auto an : ans[n]){cout << an << endl;}
}int main()
{ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);int _ = 1;std::cin >> _;ans[1].eb("1");ans[3].eb("169");ans[3].eb("196");ans[3].eb("961");for (int i = 5; i <= 99; i += 2){for (auto j : ans[i - 2]){ans[i].eb(j + "00");}int len = (i - 3) / 2;string s1 = "1";string s2 = "9";for (int j = 0; j < len; j++){s1 += "0";s2 += "0";}s1 += "6";s2 += "6";for (int j = 0; j < len; j++){s1 += "0";s2 += "0";}s1 += "9";s2 += "1";ans[i].eb(s1);ans[i].eb(s2);}while (_--){solve();}return 0;
}//
Pekora and Trampoline
CodeForces - 1491C
思路
对于 s i s_i si来说,需要经过的轮数,为 s i − f ( s i ) s_i-f(s_i) si−f(si), f ( s i ) f(s_i) f(si)表示 j + s j = i , j ≤ i j+s_j =i,j\leq i j+sj=i,j≤i,即 s i s_{i} si之前会经过 s i s_{i} si的蹦床。
为了尽可能经过尽量多的蹦床,要尽量从编号小的蹦床开始新的一轮。所以从 i = 1 i=1 i=1开始遍历,如果 s i ≠ 1 s_{i}\neq1 si=1,那么对于所有的 i + 2 ∼ i + s i i+2\sim i+s_{i} i+2∼i+si都会被经过,如果当 s i = 1 s_{i}=1 si=1时这个点被经过,那么 s i + 1 s_{i+1} si+1也会受影响。
题解
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>#define endl '\n'#define ft first
#define sd second#define yes cout << "yes\n"
#define no cout << "no\n"#define Yes cout << "Yes\n"
#define No cout << "No\n"#define YES cout << "YES\n"
#define NO cout << "NO\n"#define pb push_back
#define eb emplace_back#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"// 红色
#define DEBUG1(x) \RED; \cout << #x << " : " << x << endl; \RESET;// 绿色
#define DEBUG2(x) \GREEN; \cout << #x << " : " << x << endl; \RESET;// 蓝色
#define DEBUG3(x) \BLUE; \cout << #x << " : " << x << endl; \RESET;// 品红
#define DEBUG4(x) \MAGENTA; \cout << #x << " : " << x << endl; \RESET;// 青色
#define DEBUG5(x) \CYAN; \cout << #x << " : " << x << endl; \RESET;// 黄色
#define DEBUG6(x) \YELLOW; \cout << #x << " : " << x << endl; \RESET;using namespace std;typedef long long ll;
typedef unsigned long long ull;typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;typedef vector<vi> vvi;
typedef vector<vl> vvl;typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;template <typename T>
inline T read()
{T x = 0;int y = 1;char ch = getchar();while (ch > '9' || ch < '0'){if (ch == '-')y = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + (ch ^ 48);ch = getchar();}return x * y;
}template <typename T>
inline void write(T x)
{if (x < 0){putchar('-');x = -x;}if (x >= 10){write(x / 10);}putchar(x % 10 + '0');
}/*#####################################BEGIN#####################################*/void solve()
{int n;cin >> n;vl s(n + 5);for (int i = 1; i <= n; i++){cin >> s[i];}vl fs(n + 5); // 储存之前被经过的轮数ll ans = 0;for (int i = 1; i <= n; i++){for (int j = i + 2; j <= n && j <= i + s[i]; j++){fs[j]++;}fs[i + 1] += max(0LL, fs[i] - s[i] + 1);ans += max(0LL, s[i] - fs[i] - 1);}cout << ans << endl;
}int main()
{ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);int _ = 1;std::cin >> _;while (_--){solve();}return 0;
}// https://codeforces.com/problemset/problem/1491/C