原比赛链接

复盘:

ABC签到,手速太慢了。

D捣鼓了好久才想起来从更小的值域出发去做。

E简单二分答案。

然后就time out了。D题搞错方向浪费太久时间了。

F思维题,考虑到初值、字符集,然后是$\text{rearranged}$的,情况就很简单。

G简单位性质,拐一个弯就能想到了。

题解

D.Coprime

题意简述

给定正整数数组$a$,长度$2e5$,值域$1\le a_i \le 1000$,求最大的$i+j$满足$a_i$和$a_j$互质。

分析做法

①预处理得到$1000$以内的$gcd[i][j]$和$coprime[i][j]$。

②读入数组,对于每个$a_i$,尝试用$i$对$id[a_i]$求$\max$并更新。

③枚举$x$和$y$($1\sim1000$),如果$id[x]$和$id[y]$有值,且$x$和$y$互质,那么尝试用$id[x]+id[y]$对$ans$求$\max$并更新。

注:枚举$i+j$和$i$会$T$掉。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; const int N = 2e5;
const int M = 1000; int gcd[M + 3][M + 3];
int n, a[N + 3];
int id[M + 3]; int fgcd(int a, int b){
if(a >= b)
return gcd[a][b];
return gcd[b][a];
} bool cop(int a, int b){
return fgcd(a, b) == 1;
} void sol(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]); memset(id, 0, sizeof id);
for(int i = 1; i <= n; i++)
id[a[i]] = max(id[a[i]], i); int ans = -1;
for(int x = 1; x <= M; x++)
for(int y = 1; y <= M; y++){
if(id[x] > 0 && id[y] > 0 && fgcd(x, y) == 1)
ans = max(ans, id[x] + id[y]);
} printf("%d\n", ans); } int main(){
int a, b, r;
for(int i = 1; i <= M; i++)
for(int j = 1; j <= i; j++){
a = i;
b = j;
r = a % b;
while(r > 0){
a = b;
b = r;
r = a % b;
}
gcd[i][j] = b; } int T;
scanf("%d", &T);
while(T--)
sol(); return 0; }

E.Scuza

题意简述

给定每个台阶之间的高度差(台阶数量$2e5$,台阶高度$1e9$)。多次询问,给出腿长$k$,从头开始登台阶,问最多上到多高?($k\ge a_i$才能登上这个台阶)

分析做法

记得开$\mathrm{long\,long}$存数值。

设$premax_i=\mathop{\max}\limits_{1\le j \le i}\{a_j\}$,则$f(i)=[k\ge premax_i]$在$i\in [1,n]$上是单调的,可以二分得到能上几个台阶,预处理前缀最大值和前缀和就行。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; typedef long long LL;
const int N = 2e5; int n, q;
LL pmax[N + 3], sum[N + 3]; void sol(){
scanf("%d%d", &n, &q); LL k;
pmax[0] = sum[0] = 0;
for(int i = 1; i <= n; i++){
scanf("%lld", &k); pmax[i] = max(pmax[i - 1], k);
sum[i] = sum[i - 1] + k; } pmax[n + 1] = 1e9 + 1;
//
// while(q--){
// scanf("%lld", &k);
//
//
// for(int i = 1; i <= n + 1; i++)
// if(k < pmax[i]){
// printf("%lld ", sum[i - 1]);
// break;
//
// }
//
// } int l, r, mid, ans;
while(q--){
scanf("%lld", &k); l = 1;
r = n + 1;
ans = 0;
while(l <= r){
mid = (l + r) >> 1;
if(pmax[mid] <= k){
l = mid + 1;
ans = mid;
}
else
r = mid - 1;
} printf("%lld ", sum[ans]); } putchar('\n'); } int main(){
int T;
scanf("%d", &T);
while(T--)
sol(); return 0; }

F.Smaller

题意简述

初始两个字符串$s=t=\mathtt{a}$,然后$q$次操作,分别给$s$或$t$末尾加上$k$遍字符串$x$。

每次操作后,问能否重排$s$和$t$,使得$s$的字典序小于$t$。注意,操作影响会累积。

分析做法

因为$s$和$t$初始有一个$\mathtt{a}$,所以

①如果$t$中出现了非$\mathtt{a}$的字符,则重排时将其排在第一位,就能使得$s<t$,输出$\mathbf{YES}$

②保证$t$全部为$\mathtt{a}$,如果$s$中含有非$\mathtt{a}$的字符……

$\mathrm{i.}$要么$s$中$\mathtt{a}$个数少于$t$,情况形如$\mathtt{aab}>\mathtt{aaa}$

$\mathrm{ii.}$要么$s$中$\mathtt{a}$个数等于$t$,情况形如$\mathtt{aaab}>\mathtt{aaa}$

$\mathrm{iii.}$要么$s$中$\mathtt{a}$个数多于$t$,情况形如$\mathtt{aaaab}>\mathtt{aaa}$

所以一定输出$\mathbf{NO}$

③保证$s$和$t$全部为$\mathtt{a}$,那么如果$s$中$\mathtt{a}$个数少于$t$结果为$\mathbf{YES}$,否则为$\mathbf{NO}$。

所以实际上只需要维护$f[1]$和$f[2]$分别表示$s$和$t$是否只含$\mathtt{a}$,$c[1]$和$c[2]$分别表示$s$和$t$含有$\mathtt{a}$的个数即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; typedef long long LL;
const int N = 5e5; char s[N + 3]; void sol(){
int q, k, d;
bool f[3]; //only a?
LL c[3]; //cnt of a
f[1] = f[2] = true;
c[1] = c[2] = 1LL; scanf("%d\n", &q);
while(q--){
scanf("%d %d %s", &d, &k, s); if(f[d])
for(int i = 0; s[i]; i++)
if(s[i] != 'a'){
f[d] = false;
break;
}
else
c[d] += 1LL * k; if(!f[2])
printf("YES\n");
else
if(f[1] && c[1] < c[2])
printf("YES\n");
else
printf("NO\n"); } } int main(){
int T;
scanf("%d\n", &T);
while(T--)
sol(); return 0; }

G.Orray

题意简述

给非负整数数列$a$,重排$a$,字典序地最大化其前缀按位$\mathrm{OR}$数列。

分析做法

首先把最大值排到第一位,这样就“点亮”了一些二进制位。

接下来每步,把“已点亮”的位屏蔽之后,还没用上的元素之中找出最大值,又“点亮”了一些二进制位。

简单实现:使用$\mathrm{unsigned\,int}$类存储$a$,和“掩码”$mask$;$visit[]$数组。

每轮循环找个最大值填到下一个位置,如果没找到新的,说明没有新的二进制位可以点亮,直接把剩下的元素随便填上。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; typedef unsigned int UI;
const int N = 2e5;
const int inf = 1e9 + 1; int n;
UI a[N + 3], b[N + 3]; //b save id
bool vis[N + 3]; void sol(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]); int bpos = 0, pic;
UI mask = 0;
memset(vis, 0, sizeof vis);
while(bpos <= n){
pic = -1;
for(int i = 1; i <= n; i++)
if(!vis[i] && (a[i] & ~mask) > 0)
if(pic == -1 || (a[i] & ~mask) > (a[pic] & ~mask))
pic = i; if(pic == -1)
break; vis[pic] = true;
b[++bpos] = pic;
mask |= a[pic]; } for(int i = 1; i <= n && bpos < n; i++)
if(!vis[i])
b[++bpos] = i; for(int i = 1; i <= n; i++)
printf("%d ", a[b[i]]);
printf("\n"); } int main(){
int T;
scanf("%d\n", &T);
while(T--)
sol(); return 0; }

Codeforces Round #827 (Div. 4) 复盘+题解的更多相关文章

  1. # Codeforces Round #529(Div.3)个人题解

    Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...

  2. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...

  3. Codeforces Round #540 (Div. 3) 部分题解

    Codeforces Round #540 (Div. 3) 题目链接:https://codeforces.com/contest/1118 题目太多啦,解释题意都花很多时间...还有事情要做,就选 ...

  4. Codeforces Round #538 (Div. 2) (A-E题解)

    Codeforces Round #538 (Div. 2) 题目链接:https://codeforces.com/contest/1114 A. Got Any Grapes? 题意: 有三个人, ...

  5. Codeforces Round #531 (Div. 3) ABCDEF题解

    Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...

  6. Codeforces Round #527 (Div. 3) ABCDEF题解

    Codeforces Round #527 (Div. 3) 题解 题目总链接:https://codeforces.com/contest/1092 A. Uniform String 题意: 输入 ...

  7. Codeforces Round #499 (Div. 1)部分题解(B,C,D)

    Codeforces Round #499 (Div. 1) 这场本来想和同学一起打\(\rm virtual\ contest\)的,结果有事耽搁了,之后又陆陆续续写了些,就综合起来发一篇题解. B ...

  8. Codeforces Round #545 (Div. 1) 简要题解

    这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...

  9. Codeforces Round #624 (Div. 3)(题解)

    Codeforces Round #624 (Div.3) 题目地址:https://codeforces.ml/contest/1311 B题:WeirdSort 题意:给出含有n个元素的数组a,和 ...

  10. Codeforces Round #821(Div.2) (A-C) 题解

    Codeforces Round #821(Div.2) (A-C) A.Consecutive Sum 大致题意 给定一组共 n 个数据 ,如果俩个数的下标在 mod k 意义下同余,则可以交换a[ ...

随机推荐

  1. 五种传统IO模型

    五种传统I/O模型 作者:tsing 本文地址:https://www.cnblogs.com/TssiNG-Z/p/17089759.html 简介 提起I/O模型, 就会说到同步/异步/阻塞/非阻 ...

  2. PHP判断访问来源是PC端还是移动端

    一个方法轻松搞定,各种判断后当返回true为移动端,反之为PC端. function isMobile(){ // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($ ...

  3. python正则查找

    a = "#1+#5+#8+#10+#11+#12+#13+#14+#15-#22-#23-#24-#25-#26-#27-#28" b = re.findall("#\ ...

  4. mysql 错误解决大法 Specified key was too long; max key length is 767 bytes

    高版本mysql向低版本(5.7以下)导入sql时可能会发生此问题 开启索引最大长度 SET GLOBAL INNODB_LARGE_PREFIX = ON; 将表改为动态表SET GLOBAL in ...

  5. 【学习日志】Cglib动态代理和JDK动态代理的对比

      Cglib JDK Proxy 实现方式 生成被代理类的子类 通过被代理类实现的接口+反射 速度 慢(曾经快于JDK Proxy,但JDK Proxy几次迭代后逐渐落后) 快 限制 被代理类不能是 ...

  6. OPENMP FOR CONSTRUCT GUIDED 调度方式实现原理和源码分析

    OPENMP FOR CONSTRUCT GUIDED 调度方式实现原理和源码分析 前言 在本篇文章当中主要给大家介绍在 OpenMP 当中 guided 调度方式的实现原理.这个调度方式其实和 dy ...

  7. .net core 前端传递参数有值 后端接收到的数据却是null

    1.问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2.解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比 ...

  8. el-dialog中中使用echarts

    1.在dialog中使用open方法 <el-dialog :title="diaTitle" :visible.sync="dialogVisible" ...

  9. OpenLayers集成ECharts

    1. 引言 OpenLayers是WebGIS中常用的开源JavaScript前端库,ECharts是常用的可视化开源JavaScript前端库 OpenLayers官网:OpenLayers - W ...

  10. MATH026th: 《古今算学丛书》目录

    http://aiguji.net/2202.html 出版时间: 光绪二十四年(1898)上海算学书局据微波榭本等石印 <古今算学丛书>,刘铎辑,有光绪二十四年(1898)上海算学书局石 ...