cf1632 Codeforces Round #769 (Div. 2)题解
A ABC
水题0.0
B Roof Construction
构造题,经过实验构造出了0的右边是不超过\(n\)的最大的\(2^k\rightarrow n\),左边是\(2^k-1,2^k-2,..,1\)
明天起来看看B的证明。
可恶!出题人不写证明,那我也摸了
C Strange Test
给定两个整数\(a,b~(a<b)\),可以执行下列三种操作,每种操作都可以进行任意次:
- \(a:=a+1\)
- \(b:=b+1\)
- \(a:=a|b\)
要求输出最少需要多少次操作,可以使得\(a,b\)相等?
数据范围:\(1\leq t \leq 10^4;1\leq a<b\leq 10^6;\sum b\leq 10^6\)
猜的结论,是要么\(a:=a+1\),然后进行按位或操作;要么一直\(b:=b+1\),然后最后只会进行最多一次按位或操作。所以求出来这两种方法得到的答案,然后比较一下即可。
int x, y;
const int INF = 0x3f3f3f3f;
void solve(){
scanf("%d%d", &x, &y);
int r1 = 0, r2 = 0, res = y - x;
int a = x, b = y;
while ((a|b) != b && r1 <= res){
++a, ++r1;
}
if (a != b) ++r1;
a = x, b = y;
while ((a|b) != b && r2 <= res){
++b, ++r2;
}
if (a != b) ++r2;
res = min({res, r1, r2});
printf("%d\n", res);
}
正解当然不应该这么做!具体怎么做的明天再看。
首先,第三种操作最多用一次。因为,它不会减少\(a\),并且在操作后一定有\(b\leq a\)。这意味着,在进行操作3后,我们最多只能进行若干次操作2了。
如果我们不使用第三种操作,那么答案为\(b-a\)。
如果我们先使用了若干次操作1和操作2,然后使用了一次操作3,最后又使用了若干次操作2。
假设经过这些操作后,\(a\rightarrow a',b\rightarrow b'(a\leq a',b\leq b')\)。
此时花费的操作数为\((a'-a)+(b'-b)+1+((a'|b')-b')=a'+(a'|b')+(1-a-b)\)。
为了找到最优的答案,我们可以迭代\(a'\),令\(a'=a:b\),对于固定的\(a'\),我们要做的就是最小化\(a'|b'\),设\(b'\)初始值为0,然后从最高位到最低位迭代,有如下四种情况:
- 当前位\(a'=0,b=1\),那么当前位\(b'\)填1;
- 当前位\(a'=0,b=0\),那么当前位\(b'\)填0;
- 当前位\(a'=1,b=1\),那么当前位\(b'\)填1;
- 当前位\(a'=1,b=0\),那么当前位\(b'\)填1,终止迭代。
时间复杂度\(O(b\log b)\)或者\(O(b)\)。(第二种情况直接使用位运算把\(O(\log b)\rightarrow O(1)\)。)
嗯,这样就是最优的没有问题!
题目的Bonus:证明最优情况一定为\(a'=a\),或者\(b'=b\)。(也就是猜的结论)
int a, b;
void solve(){
scanf("%d%d", &a, &b);
int mn = b - a;
for (int ax=a;ax<=b;++ax){
int bx = 0, cur;
for (int i=20;i>=0;--i){
if (b >> i & 1){
bx += (1 << i);
}
else if (ax >> i & 1){
bx += (1 << i);
break;
}
}
cur = ax + (ax | bx) - a - b + 1;
mn = min(mn, cur);
}
printf("%d\n", mn);
}
D New Year Concert
有一个数组\(a[n]\),令\(a[n]\)的长度为\(k\)的前缀子序列\(b[k]=\{a_1,a_2,..,a_{k}\}\),如果其中有任何一个连续区间满足\(1\leq l\leq r\leq k,\gcd(b_l,b_{l+1},..,b_{r})=r-l+1\),那么就称这个序列是boring的。
为了避免\(b[k]\)boring,可以进行以下操作若干次,将\(b[k]\)中的一个元素\(b_t\)用\(d\)替换,即\(b_t=d\)。注意,每次操作的\(d,t\)都可以是不同的。定义\(f(b)\)为令数组\(b\)不再boring的最小操作次数,对于所有\(a[n]\)的前缀,求\(f([a_1]),f([a_1,a_2]),..,f([a_1,a_2,..,a_n])\)。
数据范围:\(1\leq n \leq 2\times 10^5;1\leq a_i \leq 10^9\)
嗯……首先,对于固定的左端点\(l\),随着\(r\)的增大,\(gcd(a_l,..,a_r)\)一定是不递增的。那么就有了一个很重要的性质:固定左端点,满足\(gcd(a_l,..,a_r)=r+l-1\)的\(r\)仅有一个,假如满足条件的为\(r'\)。从这里也可以看出来,boring子序列的数量最多不超过\(n\)个。那么怎样就可以消除这个boring呢?答案是在\((a_l,a_{r'})\)中的任一个数中间,修改\(a_k=\)某一个很大的质数,这个大质数要满足后面没有数是它的倍数,这里不妨设这个大质数\(p=10^9+7\)。
如果我们令\(a_i=p\),那么所有包含\(i\)的区间,boring都会消失。这是一个标准的贪心问题:找到最小的\(r\),然后所有包含\(r\)的段不再boring,删除这些段,然后继续操作。
嗯……我看的题解思路差不多,就是固定\(r\),然后找\(l\),定义\(pos\)为上一个修改了\(a[pos]\)的右端点,然后循环到\(d\geq i-pos\)时停止,当\(d=i-pos\)时,那就修改当前的\(i\),则\(pos=i\)。当然,也可以使用二分找到这样的\(d\)。区间查询\(gcd\),使用线段树即可。
(题解写的代码什么玩意 看不懂QAQ)
int n;
const int N = 2e5 + 5;
int a[N];
struct node{
int le, ri, v;
};
node seg[N<<2];
int gcd(int a, int b){
return b ? gcd(b, a % b) : a;
}
void pushup(int oo){
seg[oo].v = gcd(seg[ls].v, seg[rs].v);
}
void build(int oo, int le, int ri){
seg[oo] = {le, ri, 0};
if (le >= ri){
seg[oo].v = a[le];
return ;
}
int mid = (le + ri) >> 1;
build(ls, le, mid);
build(rs, mid + 1, ri);
pushup(oo);
}
int query(int oo, int x, int y){
int le = seg[oo].le, ri = seg[oo].ri;
if (le >= x && ri <= y){
return seg[oo].v;
}
int res = 0, mid = (le + ri) >> 1;
if (x <= mid){
res = gcd(res, query(ls, x, y));
}
if (y > mid){
res = gcd(res, query(rs, x, y));
}
return res;
}
int main(void){
scanf("%d", &n);
for (int i=1;i<=n;++i){
scanf("%d", &a[i]);
}
build(1, 1, n);
int res = 0, pos = 0;
for (int i=1;i<=n;++i){
int d = query(1, pos + 1, i);
while (d < i - pos){
pos++;
d = query(1, pos + 1, i);
}
if (d == i - pos){
res++, pos = i;
}
printf(i==n?"%d\n":"%d ", res);
}
return 0;
}
E1&E2 Distance Tree(easy & hard version )
有一棵树,根节点为1,每条边的权值为1。定义\(d(v)\)为从结点1到结点\(v\)的距离。假设从结点\(a\)出发,向某个结点连\(b\)了一条长度为\(x\)的边,定义\(f(x)=\max\{d(v)|1\leq v\leq n\}\),要求输出\(f(x)\)的最小值,\(1\leq x\leq n\)。
数据范围:\(1\leq n \leq 3\times 10^5\)
首先,应该是从结点1向其他的某个结点连边。然后要求最长的路径最短,可以想到是二分。如果我们连边的话,假设从结点1向结点\(b\)连了一个长度为\(x\)的边,并假设此时所有的边都\(\leq mid\)。那么,所有的结点要么直接按照原来的树走到1,路径长度\(\leq mid\),要么就是通过新连的边到达1,新的路径长度\(\leq mid\)。那么对于\(mid\),我们只要检查所有的\(>mid\)的路径能否变成\(\leq mid\)的路径。
设\(rt\)为到结点1距离最远的结点,则\(f[i]\):和结点1的距离\(\geq i\)时,到结点\(rt\)的最大距离。显然,我们会找到一个原本路径\(\geq i\)的点集中,两点间的最长距离。连接这个最长路的中点\(u\)和结点1,则剩下的所有点的距离都会\(\leq x+\lceil \frac{dis[u][1]}{2} \rceil\)。而当\(x\)过大时,这条路径会变得还不如原本路径,因此要和\(dis[rt][1]\)取一个最小值。
int n, rt;
const int N = 3e5 + 5;
vector<int> ve[N];
int d[N][2], f[N];
// d[i][0]:到结点1的距离; d[i][1]:到结点rt的距离
// f[i]: 和结点1的距离为>=i时, 到结点rt的最大距离
void init(){
for (int i=0;i<=n;++i){
ve[i].clear();
f[i] = d[i][0] = d[i][1] = 0;
}
}
void dfs(int u, int pre, int x){
if (pre) d[u][x] = d[pre][x] + 1;
for (auto to : ve[u]){
if (to == pre) continue;
dfs(to, u, x);
}
}
bool check(int x, int v){
return x >= min(d[rt][0], v + (f[x + 1] + 1) / 2);
}
void solve(){
n = read();
init();
int u, v;
for (int i=1;i<n;++i){
u = read(), v = read();
ve[u].push_back(v), ve[v].push_back(u);
}
dfs(1, 0, 0);
int mx = -1;
for (int i=1;i<=n;++i){
if (mx < d[i][0]){
mx = d[i][0], rt = i;
}
}
dfs(rt, 0, 1);
for (int i=1;i<=n;++i){
f[d[i][0]] = max(f[d[i][0]], d[i][1]);
}
for (int i=n-1;i>=0;--i){
f[i] = max(f[i], f[i + 1]);
}
for (int i=1;i<=n;++i){
int L = 0, R = n, ans = n;
while (L <= R){
int mid = (L + R) >> 1;
if (check(mid, i)){
ans = mid;
R = mid - 1;
}
else L = mid + 1;
}
printf("%d ", ans);
}
puts("");
}
cf1632 Codeforces Round #769 (Div. 2)题解的更多相关文章
- Codeforces Round #182 (Div. 1)题解【ABCD】
Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...
- Codeforces Round #608 (Div. 2) 题解
目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...
- Codeforces Round #528 (Div. 2)题解
Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- Codeforces Round #677 (Div. 3) 题解
Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...
- Codeforces Round #665 (Div. 2) 题解
Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
- Codeforces Round #383 (Div. 2) 题解【ABCDE】
Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...
- Codeforces Round #271 (Div. 2)题解【ABCDEF】
Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...
随机推荐
- h5py文件写入之——flush和update
技术背景 在前面的一篇博客中,我们介绍过使用VMD可视化H5MD标准化格式的轨迹文件的方法.H5MD本质上就是一个有规范格式的hdf5二进制文件,本文主要介绍两个关于hdf5的内容更新操作. 写入和更 ...
- 【Java】部门集合树状顺序展示
一.需求效果: 表单的部门下拉选择时,可以展示部门的层级: 按照这个效果展示,但是不是树,还是原来的集合 二.实现方案: 用Java代码实现两个部分 1.展示Label效果处理 2.处理集合的树状排序 ...
- error while loading shared libraries: libxml2.so.2: cannot open shared object file 解决方法
参考: https://blog.csdn.net/qq_39779233/article/details/128215517 ==================================== ...
- 【转载】 python鸭子类型与protocol
版权声明:本文为CSDN博主「yuanzhoulvpi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/yuan ...
- 5分钟教你使用idea调试SeaTunnel自定义插件
在用Apache SeaTunnel研发SM2加密组件过程中,发现社区关于本地调试SeaTunnel文章过于简单,很多情况没有说明,于是根据自己遇到问题总结这篇文档.SeaTunnel本地调试官方文档 ...
- 首次在WebAPI中写单元测试
xUnit 这次我使用的是xUnit测试框架,而不是VS自带的MSTest框架.在添加新建项目时选择xUnit测试项目就行了. 目前只体验到了一个差别,即xUnit可以使用特性向测试方法传参,而不用在 ...
- windows中好用的工具
windows中好用的工具和浏览器插件 一.geek卸载软件 软件介绍 geek一款非常简洁的卸载软件,并且非常强大,强大到可以清理注册表,用过的都说好. 下载地址: https://geekunin ...
- Camera | 4.瑞芯微平台MIPI摄像头应用程序编写
前面3篇我们讲解了camera的基础概念,MIPI协议,CSI2,常用命令等,本文带领大家入门,如何用c语言编写应用程序来操作摄像头. Linux下摄像头驱动都是基于v4l2架构,要基于该架构编写摄像 ...
- Linux-centos中修改默认root帐户的登录用户名
vi /etc/passwd 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键退出编辑状态,并输入:x保存并退出 vi /etc/shadow 按i键进入编辑状态 修改第1行第1个 ...
- .NET 智能组件完全开源
Daniel Roth在2024年3月20日发布了一篇文章: .NET 智能组件简介 – AI 驱动的 UI 控件.文章主要介绍了.NET Smart Components,这是一系列可以快速轻松地添 ...