Codeforces Round #631 (Div. 2)
48494 ワード
個人ブログ:http://www.kindkidll.com/index.php/archives/133/
試合リンク:https://codeforces.com/contest/1330
A. Dreamoon and Ranking Collection
ナレッジポイントナレッジポイント:列挙
一度列挙するだけで、現れていない数字がまだ利用可能な回数があれば、回数を1つ減らします.そうしないと、出力答えはループを終了します.
B. Dreamoon Likes Permutations
ナレッジポイントナレッジポイント:配置はいち
構想:シーケンス中の最大値をxとすると、合法的な場合は前x項+後n-x項のコンパクト配列と前n-x項+後x項のコンパクト配列の2種類しかない.すると問題は,あるシーケンスが配列であるか否かを判断することに転化する.
C. Dreamoon Likes Coloring
ナレッジポイントナレッジポイント:構築こうぞう
标题:标题中のl i l_i liは実際には固定長のブロックを与えており、起点は任意の合法的な点であり、試合で時間をかけて考えている.
考え方:前に影響を及ぼさずにできるだけ左に置くが、後ろの埋めきれない場合は適切に右に移動する.不法な場合は2つあります.現在のブロックは必ず前のブロックに影響します.後ろのブロックは後ろの区間を埋めることができません.
D. Dreamoon Likes Sequences
知識点:バイナリ+dp
重点を置く:aシーケンスとbシーケンスはいずれも厳格に増加する
考え方:b i=1∗∗∗b_i=1***bi=1∗∗∗、a i+1 a_ai+1はどんな条件を満たすべきですか?まずa i10000 a_满足的{i+1}>10000 ai+1>10000.反証法:a i+1 a_{i+1}ai+1区間[1001111][1001111][1001111]間,b i+1 b_{i+1}bi+1在区间[0000111][0000111][0000111][0000111]之间,不满足b系统的严密增加条件.a i+1 a_{i+1}ai+1区間[0000111][0000111][0000111][0000111]の間には、前のi項において、a i+1 aより大きい数が必ず存在する{i+1}ai+1も、aシキスが厳しく増加する条件を満たさない.結論:a i a_i ai的比特数严格增加了.问题是统计区间[1,d][1,d][1,d][1,d]中的不同的最高位的个数变换。include using namespace std; #define LL long long const int INF = 0x3f3f3f3f; ///1 061 109 567 const int negative_infinite = 0xcfcfcfcf; ///-808 464 433 const double pi = acos(-1); const int mod = 1e9 + 7; const double eps = 1e-8; const int MAXN = 2e5 + 117; const int MAXM = 2e5 + 117; int t; LL d, m; LL ans, cnt[37]; void build(){//最高位iの数は何個ありますか LL num = 2, t = 1; for(int i = 0; i < 32; i++) { if(d < t) cnt[i] = 0; else if(d >= num - 1) cnt[i] = t; else cnt[i] = d - t + 1; num <<= 1; t <<= 1; } } int main() { scanf("%d", &t); while(t--) { scanf("%lld%lld", &d, &m); build(); ans = 1; for(int i = 0; i < 32; i++) { ans = ans * (cnt[i] + 1) % m; } ans = ((ans - 1) % m + m) % m; printf("%lld", ans); } return 0; } E.Drazil Likes Heap知识点:工作+想张题意:给予h次完全大顶工作,如果剩下的g次完全大顶工作的和最小,需要部分删除.积分:大屋根斯塔克删除了1个诺片后,在那个诺片左右的孩子中浮出很大,g层完全大屋根斯塔克应该区间[1,2 g-1][1,2^g-1][1,2 g-1][1,2 g-1][1,2 g-1][1,2 g-1][1,2 g-1]被划分.考虑方:剩下和最小,可以大幅削减贪欲的东西,判断肝脏是怎么能削减一点?可以直接删除大的数量吗?できません.正如下图所示,直接删除7、6、5、4的话,可以得到2次大的工作,最小,但是被格纳的地方不同. は、ルートノードを削除した後に浮上する常に大きな点、すなわち、ツリー全体にわたってチェーンが全体的に移動し、このチェーンはdfsによって見つけることができることに気づくことができる.チェーンの下端が区間[1,2 g−1][1,2^g−1][1,2 g−1][1,2 g−1]にあることを発見した場合、この点は削除できない.この点を削除すると、サブノードが補充できないため、チェーンが再び上に移動する.下図に示すように、ルートノード5を削除すると、4が上に移動し、左サブツリーが空でストレージの要件に合致しません.
まとめ
久しぶりにcfを打ったのか、cfを打つ回数が少なすぎたのか、div 2の難易度が自分の予想を下回ったような気がします.しかし、試合中のコードの効率と問題を読む能力はまだ足りない.例えば、B問題試合で全く必要のない接頭辞とC問題を書いたのに40分以上かかり、D問題の意味が把握できなかった.幸い正解率はまあまあですが、cfのhackメカニズムは本当に怖いので、正解率を維持し続けたいです.
試合リンク:https://codeforces.com/contest/1330
A. Dreamoon and Ranking Collection
ナレッジポイントナレッジポイント:列挙
一度列挙するだけで、現れていない数字がまだ利用可能な回数があれば、回数を1つ減らします.そうしないと、出力答えはループを終了します.
#include
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f; ///1 061 109 567
const int negative_infinite = 0xcfcfcfcf; ///-808 464 433
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
const int MAXN = 1e5 + 117;
const int MAXM = 2e5 + 117;
int t;
int n, x;
int a[117];
bool vis[117];
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &x);
memset(vis, false, sizeof(vis));
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
vis[a[i]] = true;
}
for(int i = 1; i <= 100; i++) {
if(!vis[i]) {
if(x) x--;
else {
printf("%d
", i - 1);
break;
}
}
if(i == 100) {
printf("%d
", i + x);
break;
}
}
}
return 0;
}
B. Dreamoon Likes Permutations
ナレッジポイントナレッジポイント:配置はいち
構想:シーケンス中の最大値をxとすると、合法的な場合は前x項+後n-x項のコンパクト配列と前n-x項+後x項のコンパクト配列の2種類しかない.すると問題は,あるシーケンスが配列であるか否かを判断することに転化する.
#include
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f; ///1 061 109 567
const int negative_infinite = 0xcfcfcfcf; ///-808 464 433
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
const int MAXN = 2e5 + 117;
const int MAXM = 2e5 + 117;
int t;
bool vis[MAXN];
int n, num, cnt;
int a[MAXN], ans[7][2];
bool check(int id, int len) {
for(int i = 1; i <= len; i++) vis[i] = false;
for(int i = 0; i < len; i++) vis[a[id + i]] = true;
for(int i = 1; i <= len; i++)
if(!vis[i]) return false;
return true;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
num = 0;
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
if(num < a[i]) num = a[i];
}
cnt = 0;
if(check(0, num) && check(num, n - num)) {
ans[cnt][0] = num;
ans[cnt++][1] = n - num;
}
if(num * 2 != n && check(0, n - num) && check(n - num, num)) {
ans[cnt][0] = n - num;
ans[cnt++][1] = num;
}
printf("%d
", cnt);
for(int i = 0; i < cnt; i++) {
printf("%d %d
", ans[i][0], ans[i][1]);
}
}
return 0;
}
C. Dreamoon Likes Coloring
ナレッジポイントナレッジポイント:構築こうぞう
标题:标题中のl i l_i liは実際には固定長のブロックを与えており、起点は任意の合法的な点であり、試合で時間をかけて考えている.
考え方:前に影響を及ぼさずにできるだけ左に置くが、後ろの埋めきれない場合は適切に右に移動する.不法な場合は2つあります.現在のブロックは必ず前のブロックに影響します.後ろのブロックは後ろの区間を埋めることができません.
#include
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f; ///1 061 109 567
const int negative_infinite = 0xcfcfcfcf; ///-808 464 433
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
const int MAXN = 2e5 + 117;
const int MAXM = 2e5 + 117;
int n, m;
LL sum;
int a[MAXN], ans[MAXN];
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++) {
scanf("%d", &a[i]);
sum += a[i];
}
bool pr = true;
if(sum < n) pr = false;//
for(int i = 1; i <= m; i++) {
if(!pr) break;
if(i + a[i] - 1 > n) pr = false;//
else {
ans[i] = max((LL)i, n - sum + 1);
sum -= a[i];
}
}
if(pr) {
for(int i = 1; i <= m; i++) printf("%d ", ans[i]);
} else puts("-1");
return 0;
}
D. Dreamoon Likes Sequences
知識点:バイナリ+dp
重点を置く:aシーケンスとbシーケンスはいずれも厳格に増加する
考え方:b i=1∗∗∗b_i=1***bi=1∗∗∗、a i+1 a_ai+1はどんな条件を満たすべきですか?まずa i10000 a_满足的{i+1}>10000 ai+1>10000.反証法:a i+1 a_{i+1}ai+1区間[1001111][1001111][1001111]間,b i+1 b_{i+1}bi+1在区间[0000111][0000111][0000111][0000111]之间,不满足b系统的严密增加条件.a i+1 a_{i+1}ai+1区間[0000111][0000111][0000111][0000111]の間には、前のi項において、a i+1 aより大きい数が必ず存在する{i+1}ai+1も、aシキスが厳しく増加する条件を満たさない.結論:a i a_i ai的比特数严格增加了.问题是统计区间[1,d][1,d][1,d][1,d]中的不同的最高位的个数变换。include using namespace std; #define LL long long const int INF = 0x3f3f3f3f; ///1 061 109 567 const int negative_infinite = 0xcfcfcfcf; ///-808 464 433 const double pi = acos(-1); const int mod = 1e9 + 7; const double eps = 1e-8; const int MAXN = 2e5 + 117; const int MAXM = 2e5 + 117; int t; LL d, m; LL ans, cnt[37]; void build(){//最高位iの数は何個ありますか LL num = 2, t = 1; for(int i = 0; i < 32; i++) { if(d < t) cnt[i] = 0; else if(d >= num - 1) cnt[i] = t; else cnt[i] = d - t + 1; num <<= 1; t <<= 1; } } int main() { scanf("%d", &t); while(t--) { scanf("%lld%lld", &d, &m); build(); ans = 1; for(int i = 0; i < 32; i++) { ans = ans * (cnt[i] + 1) % m; } ans = ((ans - 1) % m + m) % m; printf("%lld", ans); } return 0; } E.Drazil Likes Heap知识点:工作+想张题意:给予h次完全大顶工作,如果剩下的g次完全大顶工作的和最小,需要部分删除.积分:大屋根斯塔克删除了1个诺片后,在那个诺片左右的孩子中浮出很大,g层完全大屋根斯塔克应该区间[1,2 g-1][1,2^g-1][1,2 g-1][1,2 g-1][1,2 g-1][1,2 g-1][1,2 g-1]被划分.考虑方:剩下和最小,可以大幅削减贪欲的东西,判断肝脏是怎么能削减一点?
#include
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f; ///1 061 109 567
const int negative_infinite = 0xcfcfcfcf; ///-808 464 433
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
const int MAXN = 3e6 + 117;
const int MAXM = 2e5 + 117;
int t;
LL sum;
int a[MAXN];
int ans[MAXN], tot;
int h, g, maxnum, tonum;
void init() {
sum = tot = 0;
tonum = 1 << g;
maxnum = 1 << h;
for(int i = 0; i < maxnum * 2; i++) a[i] = 0;
}
int getid(int i) {
if(a[i * 2] == 0 && a[i * 2 + 1] == 0) return i;
if(a[i * 2] >= a[i * 2 + 1]) return getid(i * 2);
return getid(i * 2 + 1);
}
void update(int i) {
if(a[i * 2] == 0 && a[i * 2 + 1] == 0) a[i] = 0;
else if(a[i * 2] >= a[i * 2 + 1]) {
a[i] = a[i * 2];
update(i * 2);
} else {
a[i] = a[i * 2 + 1];
update(i * 2 + 1);
}
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &h, &g);
init();
for(int i = 1; i < maxnum; i++) scanf("%d", &a[i]);
for(int i = 1; i < tonum; i++) {
while(getid(i) >= tonum) {
ans[tot++] = i;
update(i);
}
}
for(int i = 1; i < tonum; i++) sum += a[i];
printf("%lld
", sum);
for(int i = 0; i < tot; i++) printf("%d ", ans[i]);
putchar(10);
}
return 0;
}
まとめ
久しぶりにcfを打ったのか、cfを打つ回数が少なすぎたのか、div 2の難易度が自分の予想を下回ったような気がします.しかし、試合中のコードの効率と問題を読む能力はまだ足りない.例えば、B問題試合で全く必要のない接頭辞とC問題を書いたのに40分以上かかり、D問題の意味が把握できなかった.幸い正解率はまあまあですが、cfのhackメカニズムは本当に怖いので、正解率を維持し続けたいです.