Codeforces Round #520 (Div. 2) Solution
A. A Prank
Solved.
题意:
给出一串数字,每个数字的范围是$[1, 1000]$,并且这个序列是递增的,求最多擦除掉多少个数字,使得别人一看就知道缺的数字是什么。
思路:
显然,如果缺的这块数字的个数刚好等于右界 - 左界 + 1 那么就可以知道
还需要考虑数据范围,因为是$<= 1000 和 >= 1$ 那么对于两边的边界需要特殊考虑。
#include <bits/stdc++.h>
using namespace std; #define N 110
int n, a[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", a + i);
a[] = ; a[n + ] = ;
int res = , tmp = ;
for (int i = ; i <= n + ; ++i)
{
if (a[i] == a[i - ] + ) ++tmp;
else
{
res = max(res, tmp - );
tmp = ;
}
}
res = max(res, tmp - );
printf("%d\n", res);
}
return ;
}
B. Math
Solved.
题意:
给出一个数$n$, 有两种操作。
第一种是乘上一个任意整数$x$
第二种是开方,并且要保证开方后是整数。
求最少经过多少次操作,可以得到一个最小的数$n$
思路:
考虑$n$的质因数分解形式$a_1^{p_1} \cdot a_2^{p_2} \cdot a_3^{p_3} ...$
那么最小的答案就是$a_1 \cdot a_2 \cdot a_3$
因为一个数开方后是整数的话,显然是每个质因子的幂次都是偶数次,开方相当于每个质因子的幂次 $ / 2$
那么显然每个质因子最小的幂次都是1
再考虑最小的次数,因为乘法可以任意乘一个整数,所以如果需要乘法,那么乘法只需要一次。
再考虑开方,如果质因子中的最高幂次不是2的幂次,那么它不断$ / 2$ 肯定需要至少一次乘法操作,使得可以继续开方下去,直到幂次变为1
那么显然要把幂次变成一个第一个大于等于它的2的幂次数,就可以不断$ / 2$
#include <bits/stdc++.h>
using namespace std; #define N 2000010
int n, Max, res;
int Bit[N], pos[N];
vector <int> v; int solve(int x)
{
if (x == ) return ;
if (pos[x] == ) return + lower_bound(Bit + , Bit + + , x) - Bit;
for (auto it : v) if (it != x) return + pos[x];
return pos[x];
} int main()
{
Bit[] = ; pos[] = ;
for (int i = ; i <= ; ++i)
{
Bit[i] = Bit[i - ] << ;
pos[Bit[i]] = i;
}
while (scanf("%d", &n) != EOF)
{
if (n == )
{
puts("1 0");
continue;
}
v.clear();
res = ; Max = ;
for (int i = ; i <= n; ++i)
{
int tmp = ;
while (n % i == )
{
++tmp;
n /= i;
}
if (tmp)
{
res *= i;
Max = max(Max, tmp);
v.push_back(tmp);
}
}
printf("%d %d\n", res, solve(Max));
}
return ;
}
C. Banh-mi
Solved.
题意:
给出一个01串,每次询问区间$[l, r]$ 每次可以将区间内一个数取出,并且答案加上这个数的值,区间内剩余的数也加上这个值,求如何安排取出顺序使得答案最大。
思路:
显然1要在0之前取,
我们考虑区间内有$x个1, y 个 0$
那么考虑取出$x个1的答案$
显然 取出的数是形如 1 2 4 8 .....
是一个等比数列,根据求和公式发现答案为$2^x - 1$
再考虑取出的第一个0的数值为 $2^x - 1$
也是一个等比数列,和为 $(2^x - 1) \cdot (2^y - 1)$
合并两项答案 即$2^x \cdot (2^y - 1)$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
const ll MOD = (ll)1e9 + ;
int n, q, a[N]; ll qmod(ll base, ll n)
{
ll res = ;
while (n)
{
if (n & ) res = res * base % MOD;
base = base * base % MOD;
n >>= ;
}
return res;
} int main()
{
while (scanf("%d%d", &n, &q) != EOF)
{
a[] = ;
for (int i = ; i <= n; ++i) scanf("%1d", a + i), a[i] += a[i - ];
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
int x = a[r] - a[l - ], y = (r - l + ) - x;
if (x == )
{
puts("");
continue;
}
printf("%lld\n", qmod(, y) * (qmod(, x) - + MOD) % MOD);
}
}
return ;
}
D. Fun with Integers
Solved.
题意:给出一个数$n$,任意$|a| , |b| < n$ 并且满足 $|a| |b| 互为倍数关系$ 那么答案加上这个倍数,并且这一对$|a|, |b|$不再提供贡献,并且倍数关系$|x| > 1$
思路:
考虑一个数$x$, 那么在$[1, n]$ 中是它的倍数的数一共有 $y = \lfloor \frac {n}{x} \rfloor \cdot 2$ 个 因为还有负的
那么这个数的贡献是$\sum_2 ^y \cdot 2$ 再考虑 $-x$ 也会提供一样的贡献 即答案要乘2
#include <bits/stdc++.h>
using namespace std; #define ll long long
int n; int main()
{
while (scanf("%d", &n) != EOF)
{
ll res = ;
for (int i = ; i <= n; ++i)
{
ll x = n / i;
res += 2ll * (x + ) * (x - );
}
printf("%lld\n", res);
}
return ;
}
E. Company
Upsolved.
题意:
在一棵树中,每次选择一个区间$[l, r]$ 最多删除一个点,使得这个区间内所有点的$lca$ 的深度最大。
思路:
首先有一个点,就是一颗树中一堆点的$LCA$ 其实就是这堆点$DFS序最小 和 最大的两个点的LCA$
不难证明:
$我们约定用st[u] 表示点u的DFS序编号,并且约定 st[x] < st[y] <st[z], $
$根据ST求LCA 显然两个点的LCA是 st[x] 和 st[y] 中间DFS序最小的点,那么再考虑 一个点z $
$ 此处我们再对z求lca ,普通做法显然是 用st[lca(x, y)] - st[z] 之间找一个最小的$
$但实际上没有必要从st[(lca(x, y))] 开始,直接从 st[x] - st[y] 这段中找到的 pos = lca(x, y) 的位置作为左界即可$
$因为考虑 从st[lca(x, y)] - pos 这一段中,不会有DFS序编号比lca(x, y) 还要小的点,因为显然这一段序列都是在lca(x, y) 的子树中$
$如此看来,我们约定用u 表示 [l, r] 中DFS序编号最小的点,v 表示编号最大的点$
$那么LCA 就是 从 st[u] - st[v] 中找一个最小点 即为LCA$
$再考虑移除哪一个点,我们知道答案跟一段序列的最小值有关,我们要让答案有变化,要让这一段序列的区间长度有变化$
$显然是移除左边的一个点或者右边的一个点 即 DFS序编号最大的点 或者 DFS序编号最小的点$
#include <bits/stdc++.h>
using namespace std; #define INF 0x3f3f3f3f
#define N 100010
int n, q, l, r;
vector <int> G[N]; int p[N], fp[N], sze[N], son[N], fa[N], deep[N], top[N], cnt;
void DFS(int u)
{
sze[u] = ;
for (auto v : G[u]) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp = )
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
for (auto v : G[u]) if (v != son[u] && v != fa[u])
getpos(v, v);
} int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} struct SEG
{
struct node
{
int Max, Min;
void init() { Max = , Min = INF; }
node operator + (const node &r) const
{
node res; res.init();
res.Max = max(Max, r.Max);
res.Min = min(Min, r.Min);
return res;
}
}a[N << ], res;
void build(int id, int l, int r)
{
a[id].init();
if (l == r)
{
a[id].Max = a[id].Min = p[l];
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
a[id] = a[id << ] + a[id << | ];
}
void query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
res = res + a[id];
return;
}
int mid = (l + r) >> ;
if (ql <= mid) query(id << , l, mid, ql, qr);
if (qr > mid) query(id << | , mid + , r, ql, qr);
}
}seg; int lca(int l, int r)
{
seg.res.init();
seg.query(, , n, l, r);
return querylca(fp[seg.res.Min], fp[seg.res.Max]);
} int work(int x)
{
if (x == l) return deep[lca(l + , r)];
if (x == r) return deep[lca(l, r - )];
return deep[querylca(lca(l, x - ), lca(x + , r))];
} void init()
{
for (int i = ; i <= n; ++i) G[i].clear();
memset(son, , sizeof son);
cnt = ; fa[] = ; deep[] = ;
} int main()
{
while (scanf("%d%d", &n, &q) != EOF)
{
init();
for (int u = , v; u <= n; ++u)
{
scanf("%d", &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(); getpos(); seg.build(, , n);
//for (int i = 1; i <= n; ++i) printf("%d %d %d\n", i, p[i], fp[i]);
for (int qq = ; qq <= q; ++qq)
{
scanf("%d%d", &l, &r);
seg.res.init(); seg.query(, , n, l, r);
int x = fp[seg.res.Max], y = fp[seg.res.Min];
int deepx = work(x), deepy = work(y);
if (deepx > deepy) printf("%d %d\n", x, deepx);
else printf("%d %d\n", y, deepy);
}
}
return ;
}
F. Upgrading Cities
Unsolved.
Codeforces Round #520 (Div. 2) Solution的更多相关文章
- Codeforces Round #520 (Div. 2)
Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...
- Codeforces Round #466 (Div. 2) Solution
从这里开始 题目列表 小结 Problem A Points on the line Problem B Our Tanya is Crying Out Loud Problem C Phone Nu ...
- 老年OIer的Python实践记—— Codeforces Round #555 (Div. 3) solution
对没错下面的代码全部是python 3(除了E的那个multiset) 题目链接:https://codeforces.com/contest/1157 A. Reachable Numbers 按位 ...
- Codeforces Round #545 (Div. 1) Solution
人生第一场Div. 1 结果因为想D想太久不晓得Floyd判环法.C不会拆点.E想了个奇奇怪怪的set+堆+一堆乱七八糟的标记的贼难写的做法滚粗了qwq靠手速上分qwqqq A. Skyscraper ...
- Codeforces Round 500 (Div 2) Solution
从这里开始 题目地址 瞎扯 Problem A Piles With Stones Problem B And Problem C Photo of The Sky Problem D Chemica ...
- Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)
https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...
- Codeforces Round #607 (Div. 1) Solution
从这里开始 比赛目录 我又不太会 div 1 A? 我菜爆了... Problem A Cut and Paste 暴力模拟一下. Code #include <bits/stdc++.h> ...
- Codeforces Round #578 (Div. 2) Solution
Problem A Hotelier 直接模拟即可~~ 复杂度是$O(10 \times n)$ # include<bits/stdc++.h> using namespace std; ...
- Codeforces Round #520 (Div. 2) B. Math 唯一分解定理+贪心
题意:给出一个x 可以做两种操作 ①sqrt(x) 注意必须是完全平方数 ② x*=k (k为任意数) 问能达到的最小的x是多少 思路: 由题意以及 操作 应该联想到唯一分解定理 经过 ...
随机推荐
- 在create-react-app的脚手架里面使用scss
之前用vue-cli脚手架的时候,只需要引进sass需要的依赖包便可以引入scss,但是在create-react-app的时候,发现除了需要引入sass依赖,还需要进行配置: 不管用什么方法进行sa ...
- php第二例
参考: http://www.php.cn/code/3645.html 前言 由于navicat在linux平台不能很好的支持, PHP的学习转到windows平台. php IDE: PhpSto ...
- /usr/local/java/jdk1.8.0_11
- MUI ajax数据请求(list)
服务器返回格式 { "code": "1001", "message": "查询成功", "data" ...
- LNMP一键安装包phpMyAdmin无法正常登录,提示:您的Session已过期,请再次登录。
找到文件: /usr/local/php/etc/php.ini 搜索: session.auto_start = 0 修改为 session.auto_start = 1 保存即可!
- 设计模式之工厂方法模式(Java实现)
“我先来”,“不,老公,我先!”.远远的就听到几个人,哦不,是工厂方法模式和抽象工厂模式俩小夫妻在争吵,尼妹,又不是吃东西,谁先来不都一样(吃货的世界~).“抽象工厂模式,赶紧的自我介绍,工厂方法模式 ...
- Android 简单案例:可移动的View
CrossCompatibility.rar 1. VersionedGestureDetector.java import android.content.Context; import andro ...
- [Java语言] HashMap,HashSet,Hashtable,Vector,ArrayList 的关系 <转>
这么几个比较常用的但是比较容易混淆的概念同出于 java.util 包.本文仅作几个类的浅度解析. (本文基于JDK1.7,源码来自openjdk1.7.) ├── Collection │ ├── ...
- [C/C++] String Reverse 字符串 反转
#include <iostream> #include <string> #include <algorithm> #include <cstring> ...
- Android动态添加布局
//1.利用LayoutInflater的inflate动态加载XML mLinearLayout = (LinearLayout)findViewById(R.id.LinearLayout_ID) ...