A. Digits Sequence Dividing

签.

 #include <bits/stdc++.h>
using namespace std; #define N 1010
char s[N]; int n; void solve()
{
if (n == && s[] >= s[])
{
puts("NO");
return;
}
else
{
puts("YES");
puts("");
printf("%c %s\n", s[], s + );
}
} int main()
{
int t; scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
scanf("%s", s + );
solve();
}
return ;
}

B. Digital root

签.

 #include <bits/stdc++.h>
using namespace std; #define ll long long
int t;
ll k, x; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &k, &x);
printf("%lld\n", (k - ) * + x);
}
return ;
}

C. Brutality

每次连续的一段中如果大于$k个,取最大的k个$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
int n, k;
ll a[N];
char s[N]; int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%lld", a + i);
scanf("%s", s + ); s[n + ] = '#';
priority_queue <ll> pq; pq.push(a[]);
ll res = ;
for (int i = ; i <= n + ; ++i)
{
if (s[i] != s[i - ])
{
for (int j = k; !pq.empty() && j; --j)
{
res += pq.top(); pq.pop();
}
while (!pq.empty()) pq.pop();
}
pq.push(a[i]);
}
printf("%lld\n", res);
}
return ;
}

D. Compression

Solved.

题意:

有$n \cdot n的01矩阵,把矩阵压缩,压缩后的大小为\frac {n}{x}$

思路:

考虑$x | n, 枚举n的因数,在5200范围下,最多有60个$

$然后每次枚举因数n^2判断是否可以 就可以喜提TLE一枚$

$我们考虑用bitset优化$

$我们先处理出b数组第一行,然后接下来x - 1行都可以直接位运算赋值$

$那么这个复杂度就是O(\frac{n^2}{64} + (\frac{n^2}{x}))$

我们发现$< x 的因数不会太多 当因数 > x 的时候 复杂度就接近O(\frac{n^2}{64})$

$然后和a数字异或可以O(\frac{n^2}{64}) 判断合法性$

 #include <bits/stdc++.h>
using namespace std; #define N 5510
int n;
bitset <N> a[N], b[N], tmp;
char s[N][N];
char Hash[];
int res; void change(int x)
{
a[x].reset();
for (int i = , j = ; i <= n / ; ++i)
{
int num = Hash[s[x][i]];
for (int k = ; k >= ; --k)
a[x][++j] = (num >> k) & ;
}
} bool solve(int x)
{
for (int i = ; i <= n; i += x)
{
tmp.reset();
for (int j = ; j <= n; j += x)
for (int k = j; k < j + x; ++k)
tmp[k] = a[i][j];
for (int j = i; j < i + x; ++j)
{
b[j] &= ;
b[j] |= tmp;
}
}
for (int i = ; i <= n; ++i) if ((a[i] ^ b[i]) != )
{
return false;
}
return true;
} int main()
{
for (int i = ; i <= ; ++i) Hash[i + ''] = i;
Hash['A'] = ;
Hash['B'] = ;
Hash['C'] = ;
Hash['D'] = ;
Hash['E'] = ;
Hash['F'] = ;
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i)
scanf("%s", s[i] + );
for (int i = ; i <= n; ++i) change(i);
res = ;
vector <int> fac;
for (int i = ; i * i <= n; ++i) if (n % i == ) fac.push_back(i), fac.push_back(n / i);
sort(fac.begin(), fac.end());
fac.erase(unique(fac.begin(), fac.end()), fac.end());
reverse(fac.begin(), fac.end());
for (auto it : fac) if (it > )
{
if (solve(it))
{
res = it;
break;
}
}
printf("%d\n", res);
}
return ;
}

E. Vasya and Binary String

Upsolved.

题意:

有一个01串,每次可以取连续的一段相同的消除

消除后剩下的两段合并,给出连续消去$x个可以获得的价值$

求最大价值

思路:

$dp[l][r][k]表示区间[l, r]并且末尾接着k个与r相同的字符的最大价值$

$那么转移可以在[l, r]中找一个i使得s[i] = s[r] 那么答案就是 dp[l][i][k + 1] + dp[i + 1][r - 1][0]$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 110 int n;
char s[N];
ll a[N];
ll dp[N][N][N]; ll DFS(int l, int r, int k)
{
if (r < l) return ;
if (l == r) return a[k + ];
if (dp[l][r][k] != -) return dp[l][r][k];
dp[l][r][k] = a[k + ] + DFS(l, r - , );
for (int i = l; i < r; ++i) if (s[i] == s[r])
dp[l][r][k] = max(dp[l][r][k], DFS(l, i, k + ) + DFS(i + , r - , ));
return dp[l][r][k];
} int main()
{
while (scanf("%d", &n) != EOF)
{
scanf("%s", s + );
for (int i = ; i <= n; ++i) scanf("%lld", a + i);
memset(dp, -, sizeof dp);
printf("%lld\n", DFS(, n, ));
}
return ;
}

F. Vasya and Endless Credits

Upsolved.

题意:

有一个人可以向银行借款

$a_i, b_i, k_i$

$a_i表示借a_i元,b_i表示在接下来的k_i个月需要给银行b_i元钱$

求如何借款,使得其中某个月拥有最大的钱数

思路:

$dp[i]表示一共借款i个月的最大价值$

$假如我们有一个方案,那么这个方案得到的a_i的总和一样的情况下$

$我们希望将b_i大的借的月数较少,这样得到的钱数更多$

$可以先将b_i排序,再dp$

$每次可以将dp[i + 1] + dp[i] + 当前物品借i个月的价值$

$或者dp[i] 可以直接更新为加上当前月借满的状态$

$这样转移的时候就不用讨论i和k的大小关系$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 510
int n;
struct node
{
ll a, b, k;
void scan() { scanf("%lld%lld%lld", &a, &b, &k); }
bool operator < (const node &other) const { return b > other.b; }
}a[N];
ll dp[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) a[i].scan();
sort(a + , a + + n);
memset(dp, , sizeof dp);
for (int i = ; i <= n; ++i)
{
for (int j = n - ; j >= ; --j)
{
dp[j + ] = max(dp[j + ], dp[j] + a[i].a - a[i].b * j);
dp[j] = max(dp[j], dp[j] + a[i].a - a[i].b * a[i].k);
}
}
printf("%lld\n", *max_element(dp, dp + + n));
}
return ;
}

G. Vasya and Maximum Profit

Upsolved.

题意:

有一些题目,可以选择连续的一段卖出去

设题目数为$x,则得到的利润为 a \cdot x - \sum c_i - max(d[i + 1] - d[i])^2$

思路:

用线段树维护右端点的答案,再从后往前移动左端点,在考虑在左边加入一个点的答案

对右端点的贡献的影响 $影响为 a - c[i]$

$max(d[i + 1] - d[i]) ^2 这部分的影响可以用单调栈维护某个区间的最大值是多少$

$因为每个值只会被操作两次,复杂度O(nlogn)$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 300010
#define INFLL 0x3f3f3f3f3f3f3f3f
int n;
ll a, c[N], d[N];
ll val[N];
struct node
{
ll v; int l, r;
node () {}
node (ll v, int l, int r) : v(v), l(l), r(r) {}
}; namespace SEG
{
struct node
{
ll lazy, Max;
node () {}
node (ll lazy, ll Max) : lazy(lazy), Max(Max) {}
void init() { lazy = Max = ; }
void add(ll v)
{
lazy += v;
Max += v;
}
node operator + (const node &other) const
{
node res; res.init();
res.Max = max(Max, other.Max);
return res;
}
}a[N << ];
void init() { memset(a, , sizeof a); }
void pushdown(int id)
{
if (!a[id].lazy) return;
a[id << ].add(a[id].lazy);
a[id << | ].add(a[id].lazy);
a[id].lazy = ;
}
void update(int id, int l, int r, int ql, int qr, ll v)
{
if (l >= ql && r <= qr)
{
a[id].add(v);
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (ql <= mid) update(id << , l, mid, ql, qr, v);
if (qr > mid) update(id << | , mid + , r, ql, qr, v);
a[id] = a[id << ] + a[id << | ];
}
ll query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[id].Max;
int mid = (l + r) >> ;
pushdown(id);
ll res = ;
if (ql <= mid) res = max(res, query(id << , l, mid, ql, qr));
if (qr > mid) res = max(res, query(id << | , mid + , r, ql, qr));
return res;
}
} int main()
{
while (scanf("%d%lld", &n, &a) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%lld%lld", d + i, c + i);
for (int i = ; i <= n; ++i) val[i] = (d[i] - d[i - ]) * (d[i] - d[i - ]);
SEG::init();
stack <node> sta;
ll res = ;
for (int i = n; i >= ; --i)
{
SEG::update(, , n, i, n, a - c[i]);
if (i != n)
{
node now = node(val[i + ], i + , i + );
while (!sta.empty())
{
node tmp = sta.top();
if (now.v >= tmp.v)
{
SEG::update(, , n, tmp.l, tmp.r, tmp.v);
now.r = tmp.r;
sta.pop();
}
else
break;
}
SEG::update(, , n, now.l, now.r, -now.v);
sta.push(now);
}
res = max(res, SEG::query(, , n, i, n));
sta.push(node(, i, i));
}
printf("%lld\n", res);
}
return ;
}

Educational Codeforces Round 59 Solution的更多相关文章

  1. Educational Codeforces Round 59 (Rated for Div. 2) DE题解

    Educational Codeforces Round 59 (Rated for Div. 2) D. Compression 题目链接:https://codeforces.com/contes ...

  2. Educational Codeforces Round 59 (Rated for Div. 2) E 区间dp + 状态定义 + dp预处理(分步dp)

    https://codeforces.com/contest/1107/problem/E 题意 给出01字符串s(n<=100),相邻且相同的字符可以同时消去,一次性消去i个字符的分数是\(a ...

  3. C. Brutality Educational Codeforces Round 59 (Rated for Div. 2) 贪心+思维

    C. Brutality time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  4. Educational Codeforces Round 59

    B. Digital root 题意: 题目定义了x的digital root是S(x).S(5)=5,S(38)=S(3+8=11)=S(1+1+2)=2. 有n个询问,每次询问给出ki和xi,要你 ...

  5. Educational Codeforces Round 56 Solution

    A. Dice Rolling 签到. #include <bits/stdc++.h> using namespace std; int t, n; int main() { scanf ...

  6. Educational Codeforces Round 57 Solution

    A. Find Divisible 签到. #include <bits/stdc++.h> using namespace std; int t, l, r; int main() { ...

  7. Educational Codeforces Round 58 Solution

    A. Minimum Integer 签到. #include <bits/stdc++.h> using namespace std; #define ll long long ll l ...

  8. Educational Codeforces Round 59 (Rated for Div. 2)

    熬夜爆肝,智商急剧下降 坐标UTC+8晚上23:35开始 晚上脑袋转的慢,非常慢 T1上来先做还花了好几分钟 T2本来是有式子的我TM写数位DP写炸了然后才发现是有公式 T3英语不好,一开始题意没读懂 ...

  9. 【考试记录】Educational Codeforces Round 59 (Rated for Div. 2)

    本来准备划水,结果被垃圾题艹翻了…… T2题意: 定义一个数$x$的数字根$S(x)$为:将其各位数字相加得到一个新数,再将新数的数字和相加直到得到一个个位数,就是该数的数字根. 例如:$S(38)= ...

随机推荐

  1. ionic creator(ionic生成器)

    用来生成前端 html 还是挺方便的(接口数据另算),弄好就可以直接下载 https://creator.ionic.io/app/dashboard/projects

  2. Redis(一)-- 基础

    一.Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内 ...

  3. Google Inc.:Google APIs:23' 解决方案

    在导入一个项目是,出现 Unable to resolve target 'Google Inc.:Google APIs:6'第一种解决方法: compileSdkVersion 23 改成 com ...

  4. vue中的小踩坑(01)

    前言: 昨天算是使用vue2.0+element-ui做了一点小小的页面,可是源于其中遇到的问题,特地整理一下,以防自己还有其他的小伙伴们继续踩坑. 过程:         1.不知道大家有没有注意到 ...

  5. lodash(一)数组

    前言: lodash是一个具有一致接口.模块化.高性能等特性的JavaScript工具库(官网地址:http://lodashjs.com/docs/#_differencearray-values) ...

  6. 《转》python学习(6)序列类型-字符串

    转自 http://www.cnblogs.com/BeginMan/archive/2013/06/08/3125502.html 二.序列类型 包含字符串.列表.元祖.模式都一样,举一反三即可.如 ...

  7. synchronized同步语句块

    用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待比较长时间.在这样的情况下可以使用synchronized同步语句块来解 ...

  8. 【BZOJ3156】防御准备 斜率优化

    [BZOJ3156]防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小 ...

  9. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  10. Python老王视频习题答案

    基础篇2:一切变量都是数据对象的引用sys.getrefcount('test') 查看引用计数变量命名不能以数字开头编码:ascii.unicode.utf-81.阅读str对象的help文档,并解 ...