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的更多相关文章

  1. Codeforces Round #520 (Div. 2)

    Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...

  2. Codeforces Round #466 (Div. 2) Solution

    从这里开始 题目列表 小结 Problem A Points on the line Problem B Our Tanya is Crying Out Loud Problem C Phone Nu ...

  3. 老年OIer的Python实践记—— Codeforces Round #555 (Div. 3) solution

    对没错下面的代码全部是python 3(除了E的那个multiset) 题目链接:https://codeforces.com/contest/1157 A. Reachable Numbers 按位 ...

  4. Codeforces Round #545 (Div. 1) Solution

    人生第一场Div. 1 结果因为想D想太久不晓得Floyd判环法.C不会拆点.E想了个奇奇怪怪的set+堆+一堆乱七八糟的标记的贼难写的做法滚粗了qwq靠手速上分qwqqq A. Skyscraper ...

  5. Codeforces Round 500 (Div 2) Solution

    从这里开始 题目地址 瞎扯 Problem A Piles With Stones Problem B And Problem C Photo of The Sky Problem D Chemica ...

  6. Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)

    https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...

  7. Codeforces Round #607 (Div. 1) Solution

    从这里开始 比赛目录 我又不太会 div 1 A? 我菜爆了... Problem A Cut and Paste 暴力模拟一下. Code #include <bits/stdc++.h> ...

  8. Codeforces Round #578 (Div. 2) Solution

    Problem A Hotelier 直接模拟即可~~ 复杂度是$O(10 \times n)$ # include<bits/stdc++.h> using namespace std; ...

  9. Codeforces Round #520 (Div. 2) B. Math 唯一分解定理+贪心

    题意:给出一个x 可以做两种操作  ①sqrt(x)  注意必须是完全平方数  ② x*=k  (k为任意数)  问能达到的最小的x是多少 思路: 由题意以及 操作  应该联想到唯一分解定理   经过 ...

随机推荐

  1. Python 常见文件操作的函数示例(转)

    转自:http://www.cnblogs.com/txw1958/archive/2012/03/08/2385540.html # -*-coding:utf8 -*- ''''' Python常 ...

  2. div位置设置

    div居中显示 margin:0 auto div中的内容居中显示 text-algin:center div靠右显示 float:right 设置div元素的右外边距 margin-right:10 ...

  3. ELK5.X+logback搭建日志平台

    一.背景 当生产环境web服务器做了负载集群后,查询每个tomcat下的日志无疑是一件麻烦的事,elk为我们提供了快速查看日志的方法. 二.环境 CentOS7.JDK8.这里使用了ELK5.0.0( ...

  4. 第二篇:一个经典的比喻( 关于TCP连接API )

    前言 编程是对现实世界的模拟,网络通信自然也是对现实世界通信的模拟.可以将网络通信中使用的各种API和对现实世界中的各种通信设备进行通讯的操作进行对比以加深理解. 对比 socket() 函数 vs ...

  5. fgetc read缓冲机制区别

    read属于系统调用,它的缓存是基于内核的缓冲,是记在内核空间的. 而fgetc是标准函数, 是在用户空间I/O缓冲区的 比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O ...

  6. Windows下Nutch的配置

    Nutch是一个开源的.Java实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具. Nutch可以分为2个部分: 抓取部分crawler 抓取程序抓取页面并把抓取回来的数据做成反向索引 搜 ...

  7. Spring AOP教程及实例

    1.教程转载==>>:http://blog.csdn.net/wangpeng047/article/details/8556800 2.实例转载==>>:http://bl ...

  8. Delphi数据类型转换

    [转]Delphi数据类型转换 DateTimeToFileDate        将DELPHI的日期格式转换为DOS的日期格式 DateTimeToStr              将日期时间格式 ...

  9. java高级---->Thread之FutureTask的使用

    FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行.今天我们通过实例来学习一下FutureTask的 ...

  10. HTTP/2笔记之消息交换

    前言 无论是HTTP/1.*还是HTTP/2,HTTP的基本语义是不变的,比如方法语义(GET/PUST/PUT/DELETE),状态码(200/404/500等),Range Request,Cac ...