Codeforces Round #631 (Div. 2)
Posted zhltao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #631 (Div. 2)相关的知识,希望对你有一定的参考价值。
这场打的有点小开心呀,最后交过 T4 ,但是T3 的线段树居然炸了,也不知道是为啥....反正拿 (O(n)) 做法搞过去了....
Problem A
没什么好说的,随便瞎搞
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read()
{
T x = 0;
char ch = getchar();
bool f = 0;
while(ch < ‘0‘ || ch > ‘9‘)
{
f = (ch == ‘-‘);
ch = getchar();
}
while(ch <= ‘9‘ && ch >= ‘0‘)
{
x = (x << 1) + (x << 3) + (ch - ‘0‘);
ch = getchar();
}
return f? -x : x;
}
template <typename T>
void put(T x)
{
if(x < 0)
{
x = -x;
putchar(‘-‘);
}
if(x < 10) {
putchar(x + 48);
return;
}
put(x / 10);
putchar(x % 10 + 48);
return ;
}
#define rd read <int>
#define pt(i) put <int> (i), putchar(‘
‘)
#define ptY puts("YES")
#define ptN puts("NO")
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef unsigned long long ull;
typedef unsigned int ui;
const int Maxn = 2e2 + 111;
int x, t, n;
bool flag[Maxn];
int main()
{
#ifdef _DEBUG
freopen("in.txt", "r", stdin);
#endif
t = rd();
while(t--)
{
memset(flag, 0, sizeof flag);
n = rd(); x = rd();
for(int i = 1; i <= n; ++i)
flag[rd()] = 1;
int len = 0;
while(x > 0 || flag[len + 1])
{
if(!flag[len + 1]) --x;
len++;
}
pt(len);
}
return 0;
}
Problem B
这题吗,就是注意到 (Max_{ans} = 2),注意判一下两个一样
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read()
{
T x = 0;
char ch = getchar();
bool f = 0;
while(ch < ‘0‘ || ch > ‘9‘)
{
f = (ch == ‘-‘);
ch = getchar();
}
while(ch <= ‘9‘ && ch >= ‘0‘)
{
x = (x << 1) + (x << 3) + (ch - ‘0‘);
ch = getchar();
}
return f? -x : x;
}
template <typename T>
void put(T x)
{
if(x < 0)
{
x = -x;
putchar(‘-‘);
}
if(x < 10) {
putchar(x + 48);
return;
}
put(x / 10);
putchar(x % 10 + 48);
return ;
}
#define rd read <int>
#define pt(i) put <int> (i), putchar(‘
‘)
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef unsigned long long ull;
typedef unsigned int ui;
const int Maxn = 2e5 + 111;
int t, a[Maxn], cnt[Maxn], n, max1, ans;
int main()
{
#ifdef _DEBUG
freopen("in.txt", "r", stdin);
#endif
t = rd();
while(t--)
{
n = rd();
max1 = 0;
for(int i = 1; i <= n; ++i)
{
a[i] = rd();
max1 = max(max1, a[i]);
}
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= max1; ++i) cnt[a[i]]++;
bool flag = 0;
ans = 0;
for(int i = 1; i <= max1; ++i)
if(cnt[i] != 1)
{
flag = 1;
break;
}
if(!flag)
{
memset(cnt, 0, sizeof cnt);
for(int i = max1 + 1; i <= n; ++i) cnt[a[i]]++;
for(int i = 1; i <= n - max1; ++i)
if(cnt[i] != 1)
{
flag = 1;
break;
}
}
ans += !flag;
bool flag1 = 0;
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= max1; ++i) cnt[a[n - i + 1]]++;
for(int i = 1; i <= max1; ++i) if(cnt[i] != 1) { flag1 = 1;break;}
if(!flag1)
{
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= n - max1; ++i) cnt[a[i]]++;
for(int i = 1; i <= n - max1; ++i)
if(cnt[i] != 1)
{
flag1 = 1;
break;
}
}
ans += !flag1;
if(!flag1 && !flag && n % 2 == 0 && max1== n / 2)
{
pt(1);
put(max1);
putchar(‘ ‘);
pt(n - max1);
continue;
}
pt(ans);
if(!flag)
{
put(max1);
putchar(‘ ‘);
pt(n - max1);
}
if(!flag1)
{
put(n - max1);
putchar(‘ ‘);
pt(max1);
}
}
return 0;
}
Problem C
随便瞎搞就行了,考虑覆盖,记下起点与终点
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read() {
T x = 0;
char ch = getchar();
bool f = 0;
while (ch < ‘0‘ || ch > ‘9‘) {
f = (ch == ‘-‘);
ch = getchar();
}
while (ch <= ‘9‘ && ch >= ‘0‘) {
x = (x << 1) + (x << 3) + (ch - ‘0‘);
ch = getchar();
}
return f ? -x : x;
}
template <typename T>
void put(T x) {
if (x < 0) {
x = -x;
putchar(‘-‘);
}
if (x < 10) {
putchar(x + 48);
return;
}
put(x / 10);
putchar(x % 10 + 48);
return;
}
#define rd read<int>
#define pt(i) put<int>(i), putchar(‘ ‘)
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef unsigned long long ull;
typedef unsigned int ui;
const int Maxn = 2e5 + 111;
int n, m, l[Maxn], p[Maxn], oo = 0;
int main() {
n = rd();
m = rd();
for (int i = 1; i <= m; ++i) l[i] = rd();
int coo;
for (int i = m; i >= 1; --i) {
coo = min(l[i], n - oo - i + 1);
if (coo <= 0) {
printf("-1
");
return 0;
}
p[i] = max(1, oo + coo - l[i] + 1);
oo = p[i] + l[i] - 1;
}
if (oo != n) {
printf("-1");
return 0;
}
for (int i = 1; i <= m; ++i) pt(p[i]);
return 0;
}
或说,我真正要说的是 D 题,说一个非常愉悦的 dp 想法
Problem D
考虑一个性质,我们可以证明
定义 (p_(i)) 为 (a_i) 的位数(即最高位一)
只要满足这个就有题目条件成立,于是我们可以设计状态 (f[i][j]) 表示在 前 (i) 位的数里只选了 (j) 个,那么我们的所求即为 (sum_{1le i le cnt} f[cnt][i]) 。于是很显然的列出状态转移方程
其中,(b[i]) 表示 这一位中能选几个
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read()
{
T x = 0;
char ch = getchar();
bool f = 0;
while(ch < ‘0‘ || ch > ‘9‘)
{
f = (ch == ‘-‘);
ch = getchar();
}
while(ch <= ‘9‘ && ch >= ‘0‘)
{
x = (x << 1) + (x << 3) + (ch - ‘0‘);
ch = getchar();
}
return f? -x : x;
}
template <typename T>
void put(T x)
{
if(x < 0)
{
x = -x;
putchar(‘-‘);
}
if(x < 10) {
putchar(x + 48);
return;
}
put(x / 10);
putchar(x % 10 + 48);
return ;
}
#define rd read <long long>
#define pt(i) put <long long> (i), putchar(‘
‘)
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef unsigned long long ull;
typedef unsigned int ui;
const int Maxn = 111;
ll b[40], n, d, f[Maxn][Maxn], cnt, t;
bool flag;
int main()
{
#ifdef _DEBUG
freopen("in.txt", "r", stdin);
#endif
t = rd();
while(t--)
{
n = rd();
flag = 0;
d = rd();
b[1] = 1;
cnt = 1;
n -= 1;
for(int i = 1 + 1; i <= 31 && n > 0; ++i)
{
b[i] = b[i - 1] << 1;
n -= b[i];
if(n <= 0)
{
cnt = i;
b[i] += n;
}
}
f[0][0] = 1;
for(int i = 1; i <= cnt; ++i)
{
f[i][0] = 1;
for(int j = 1; j <= i; ++j)
f[i][j] = (f[i - 1][j - 1] * b[i] % d + f[i - 1][j]) % d;
}
ll ans = 0;
for(int i = 1; i <= cnt; ++i) ans = (ans + f[cnt][i]) % d;
pt(ans);
}
return 0;
}
嵬
这几场确实上分比较快,因为由于某种原因,打的人比较多...
以上是关于Codeforces Round #631 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #344 (Div. 2) 631 C. Report (单调栈)
Codeforces Round #631 (Div. 2) B. Dreamoon Likes Permutations(排列组合)
Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!
Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!
Codeforces Round #631 (Div. 2) Dreamoon Likes Sequences
Codeforces Round #631 (Div. 2) C. Dreamoon Likes Coloring(贪心好题/意识流题解)