A - Thermometer

按题意判断并输出即可。

时间复杂度\(O(1)\)。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
double x;
signed main(){
cin>>x;
if(x>=38) cout<<"1\n";
else if(x>=37.5) cout<<"2\n";
else cout<<"3\n";
return 0;
}

B - Ticket Gate Log

令\(c\)表示当前位应为哪个字符,初始为i

从左到右遍历每个字符\(s_i\):

  • 如果\(s_i=c\),就将\(c\)取反;
  • 如果\(s_i\ne c\),就累加\(1\)的贡献。

时间复杂度\(O(n)\)。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s;
int ans=0;
char c='i';
signed main(){
cin>>s;
for(char i:s){
if(i==c) c=(c=='i'?'o':'i');
else ans++;
}
cout<<ans+(c=='o')<<"\n";
return 0;
}

C - Variety Split Easy

分别令\(lef_i,rig_i\)表示\(A\)长度为\(i\)的前缀和后缀有多少不同的元素。

则答案为\(\max\limits_{i=1}^{n-1} (lef_i+rig_i)\)。

\(lef,rig\)可以在遍历过程中,用桶计算出来。

可以用数组、unordered_set等数据结构作为桶。

时间复杂度为\(O(n)\)。

点击查看代码
#include<bits/stdc++.h>
#define N 300010
using namespace std;
int n,a[N],ans;
unordered_set<int> se;
int lef[N],rig[N];
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
se.insert(a[i]);
lef[i]=se.size();
}
se.clear();
for(int i=n;i>=1;i--) se.insert(a[i]),rig[i]=se.size();
for(int i=1;i<n;i++) ans=max(ans,lef[i]+rig[i+1]);
cout<<ans<<"\n";
return 0;
}

D - Cubes

因式分解可得:\(x^3-y^3=(x-y)(x^2+xy+y^2)\)。

如果我们可以枚举\(d=x-y\),即\(x=d+y\)……

那我们仅需判断\(N=d[(d+y)^2+(d+y)y+y^2]\),即\(3y^2+3dy+(d^2-\frac{N}{d})=0\)是否有正整数解即可。

由于\(x^2+xy+y^2\ge (x-y)^3\),所以\((x-y)^3\le N\),即\(d\le \sqrt[3]{N}\),因此枚举\(d\)的时间复杂度是\(O(\sqrt[3]{N})\)。

接下来考虑对于每个\(d\),如何判断是否有整数解。

  • 可以用二次方程求根公式完成判定,时间复杂度为\(O(1)\),不过实现起来比较繁琐;
  • 考虑到二次项、一次项系数都为正,所以上式在\(x>0\)时是单增的,所以我们也可以使用二分法

    显然仅需在\([1,\sqrt N]\)内二分即可,时间复杂度为\(O(\log\sqrt N)\),实现起来较为简单。

代码使用二分法,总时间复杂度为\(O(\sqrt[3]{N}\log\sqrt N)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int solve(int a,int b,int c){
int l=1,r=1e9;
while(l<r){
int x=(l+r+1)>>1;
if(a*x*x+b*x+c<=0) l=x;
else r=x-1;
}
return a*l*l+b*l+c==0?l:-1;
}
signed main(){
cin>>n;
for(int d=1;d*d*d<=n;d++){
if(n%d) continue;
int y=solve(3,3*d,d*d-n/d);
if(~y) cout<<d+y<<" "<<y<<"\n",exit(0);
}
cout<<"-1\n";
return 0;
}

E - Path Decomposition of a Tree

定义\(siz_u\)为子树\(u\)的大小,\(fa_u\)为\(u\)的父节点,\(ch_u\)为\(u\)的子节点个数。

定义\(t_u=siz_u\bmod k\)。不难发现,其含义就是“为了将子树\(u\)的节点全部用链覆盖,子树\(u\)外最少要用多少个节点”。

比如\(t_u=0\)就表示子树\(u\)的答案为Yes

选定一个节点\(R\)作为根节点,开始遍历每棵树,对于节点\(u\),输出No的情况显然只有下面\(3\)种:

  • \((\sum\limits_{fa_v=u} [t_v\ne 0])>2\)。
  • \((\sum\limits_{fa_v=u} t_v)+1>k\)。
  • \(ch_u=2\)且\((\sum\limits_{fa_v=u} t_v)\ne k\)。

特别地,对于根节点\(R\),如果\(t_R\ne 0\),输出No

不过根据数据范围,节点数一定是\(k\)的倍数,所以一定有\(t_R=0\),就不用讨论了。

时间复杂度\(O(nk)\)。

点击查看代码
#include<bits/stdc++.h>
#define NN 200010
#define int long long
using namespace std;
int n,k;
vector<int> G[NN];
void add(int u,int v){G[u].emplace_back(v);}
int dfs(int u,int fa){
int cnt=0,sum=1;
for(int i:G[u]){
if(i==fa) continue;
int t=dfs(i,u);
if(!t) continue;
if(cnt==2) cout<<"No\n",exit(0);
sum+=t,cnt++;
}
if(sum>k||(cnt==2&&sum!=k)) cout<<"No\n",exit(0);
return sum%k;
}
signed main(){
cin>>n>>k;
for(int i=1,u,v;i<n*k;i++){
cin>>u>>v;
add(u,v),add(v,u);
}
dfs(1,0);
cout<<"Yes\n";
return 0;
}

F - Variety Split Hard

如果第\(2\)个区间的右端点已经确定为\(i\),我们仅需考虑第\(1\)个区间的右端点如何选择,即\(a_{1\sim i}\)分成\(2\)个区间的答案。

先考虑用另一种方法解决C——统计每一个位置对答案的贡献。

  • 如果\(a_i\)在\(a_{1\sim i}\)中是唯一的,那么第\(1\)个区间的右端点设在任何位置都会产生\(1\)的贡献。
  • 如果\(a_i\)在\(a_{1\sim i}\)中不是唯一的,定义\([1,i)\)中最大的\(p\)使得\(a_p=a_i\),那么:
    • 如果第\(1\)个区间的右端点\(\in [p,i)\),则对该位置产生\(1\)的贡献。
    • 否则对该位置产生\(0\)的贡献。

用线段树维护每个位置的总贡献,这些总贡献的最大值即为答案。

之所以用这种方法来考虑C题,是因为它可以很轻易地被推广。仅需顺序遍历\(i\in [1,n]\),在统计完前\(i\)个的贡献之后,就用\([1,i]\)每个位置总贡献的最大值,再加上“\(a_{(i+1)\sim n}\)中互不相同的值的个数”,更新答案即可。

按上面的步骤,会把区间为空的情况一并统计进来。不过想一想就能发现,存在空区间的答案一定不会优于每个区间都非空的答案。所以正确性是可以保证的。

时间复杂度\(O(n\log n)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 300010
#define lc (x<<1)
#define rc (x<<1|1)
using namespace std;
int n,a[N],suf[N],last[N],ans;
bitset<N> vis;
struct Node{int tag,maxx;}s[N<<2];
void build(int x,int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
build(lc,l,mid),build(rc,mid+1,r);
}
void pushdown(int x){
s[lc].maxx+=s[x].tag,s[lc].tag+=s[x].tag;
s[rc].maxx+=s[x].tag,s[rc].tag+=s[x].tag;
s[x].tag=0;
}
void chr(int x,int a,int b,int l,int r,int v){
if(a<=l&&r<=b) return s[x].maxx+=v,s[x].tag+=v,void();
pushdown(x);
int mid=(l+r)>>1;
if(a<=mid) chr(lc,a,b,l,mid,v);
if(b>mid) chr(rc,a,b,mid+1,r,v);
s[x].maxx=max(s[lc].maxx,s[rc].maxx);
}
int query(int x,int a,int b,int l,int r){
if(a<=l&&r<=b) return s[x].maxx;
pushdown(x);
int mid=(l+r)>>1,ans=0;
if(a<=mid) ans=max(ans,query(lc,a,b,l,mid));
if(b>mid) ans=max(ans,query(rc,a,b,mid+1,r));
return ans;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=n;i>=1;i--) suf[i]=suf[i+1]+!vis[a[i]],vis[a[i]]=1;
build(1,1,n);
for(int i=1;i<=n;i++){
if(last[a[i]]) chr(1,last[a[i]],i-1,1,n,1);
else chr(1,1,n,1,n,1);
last[a[i]]=i;
ans=max(ans,suf[i+1]+query(1,1,i,1,n));
}
cout<<ans<<"\n";
return 0;
}

这道题还有加强版:https://codeforces.com/problemset/problem/833/B,如果有空会写题解。

[题解]AtCoder Beginner Contest 397(ABC397) A~F的更多相关文章

  1. 题解 AtCoder Beginner Contest 168

    小兔的话 欢迎大家在评论区留言哦~ AtCoder Beginner Contest 168 A - ∴ (Therefore) B - ... (Triple Dots) C - : (Colon) ...

  2. 【AtCoder Beginner Contest 181】A~F题解

    越学越菜系列 于2020.11.2,我绿了(错乱) A - Heavy Rotation 签到题,奇数Black,偶数White. code: #include<bits/stdc++.h> ...

  3. AtCoder Beginner Contest 127 D,E,F

    D Integer Cards 题意:先给出n个数字,然后可以有m次操作,每次操作以数字对(x,y)表示最多能选x个数字把它变成y,问经历m次操作后n个数字和最大为多少? 解法:一个明显正确的做法是: ...

  4. [题解] Atcoder Beginner Contest ABC 270 G Ex 题解

    点我看题 G - Sequence in mod P 稍微观察一下就会发现,进行x次操作后的结果是\(A^xS+(1+\cdots +A^{x-1})B\).如果没有右边那一坨关于B的东西,那我们要求 ...

  5. [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT

    题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...

  6. AtCoder Beginner Contest 238 A - F 题解

    AtCoder Beginner Contest 238 \(A - F\) 题解 A - Exponential or Quadratic 题意 判断 \(2^n > n^2\)是否成立? S ...

  7. AtCoder Beginner Contest 137 F

    AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...

  8. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  9. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  10. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

随机推荐

  1. Java中判断某一字符串是否包含数字、字母和中文

         在Java中判断某一字符串是否为纯英文.纯数字.英文和数字的组合等时,通常使用正则str.matches匹配,告诉这个字符串是否与给定的正则表达式匹配.  各种字符的unicode编码的范围 ...

  2. 2023人形全能赛openmv巡线代码

    openmv import sensor, image, time, math from pyb import LED, millis, UART class RobotControl: flag = ...

  3. Easing缓动函数宝藏网站

    鼠标放上去,就可以查看速度变化了 找了很久,终于找到了,大家可以收藏起来,很好用 https://easings.net/

  4. 深入探讨控制反转(IOC)与依赖注入(DI)模式原理与应用实践

    本文由 ChatMoney团队出品 在软件开发中,控制反转(Inversion of Control,简称IOC)和依赖注入(Dependency Injection,简称DI)是两种常用的设计模式, ...

  5. 关于ant design pro的权限方案设计

    ​ 访问控制(Access control)是指对访问者向受保护资源进行访问操作的控制管理.该控制管理保证被授权者可访问受保护资源,未被授权者不能访问受保护资源. 现实生活中的访问控制可以由付费或者认 ...

  6. CentOS云服务器WordPress搭建(BT.CN)

    该随笔为大学时期的建站记录,图片等等,由于域名到期,七牛云回收资源,图床失效等等,已无法考究,语雀也没法恢复文档,仅作为参考用. 此教程适用于国内的建站,英文外贸建站请移步购买位于国外的服务器[外贸建 ...

  7. Vertx 接入Redis (八)

    项目github地址:https://github.com/fotocj007/VertxWebApi web服务器经典的mysql+redis模式,这里介绍redis的接入. 一:导入gradle ...

  8. 四、设备修改开机logo

    2.1.修改开机logo 图片文件路径 (替换以下文件): ./kernel/logo.bmp ./kernel/logo_kernel.bmp 设备树配置路径(配置为开启显示logo): ./boo ...

  9. 别再被 Spring Security 和 Shiro 劝退了!这款国产 Java 权限框架真香!

    Hello,大家好,我是程序员NEO. 在 Java 开发中,权限认证是个绕不开的话题.但一提起 Spring Security 或 Shiro,很多人是不是瞬间就头大了?复杂的配置.陡峭的学习曲线, ...

  10. pdf渲染和对比 react-pdf-highlighter

    前言 react-pdf-highlighter 使用此插件 做pdf的预览 高亮 批注 对比等 效果 地址 https://github.com/dingshaohua-cn/pdf-highlig ...