A - Approximation

使用<cmath>中的round()函数实现四舍五入。

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

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int a,b;
signed main(){
cin>>a>>b;
cout<<round(1.0*a/b);
return 0;
}

B - P(X or Y)

枚举两次的点数,统计满足条件的个数,最后求出比例即可。

时间复杂度\(O(|\Sigma|^2)\),其中\(|\Sigma|=6\)。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int x,y,cnt;
signed main(){
cin>>x>>y;
for(int i=1;i<=6;i++){
for(int j=1;j<=6;j++){
if(i+j>=x||abs(i-j)>=y) cnt++;
}
}
cout<<fixed<<setprecision(18)<<1.0*cnt/36<<"\n";
return 0;
}

C - Security 2

考虑把过程倒过来,先让最后一位通过\(-1\)操作变成\(0\),然后向前以此类推……

注意\(+1\)操作是所有数共同进行的,所以我们需要记录\(cnt\)变量表示到目前为止的\(+1\)操作个数,处理某位时,需要先对该位进行\(cnt\)次\(-1\)操作,再统计贡献。

别忘了添加\(0\)也是一次操作。

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

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
string s;
int n,cnt;
signed main(){
cin>>s;
n=s.size();
for(int i=n-1;~i;i--){
int v=(s[i]-'0'-cnt)%10;
(v+=10)%=10;
cnt+=v;
}
cnt+=n;
cout<<cnt<<"\n";
return 0;
}

D - Domino Covering XOR

DFS搜索骨牌的放置方案,从左上角开始,遇到一个空格子,那么这个格子可以有\(3\)种状态:

  • 与右边的格子共用一张骨牌。
  • 与下边的格子共用一张骨牌。
  • 不放骨牌。

不过这样子方案数太多,因为覆盖格子集合相同的情况下,我们还在考虑骨牌的不同放置方法,然而这是冗余的。

所以用\(f[x][y][S]\)记忆化一下就可以了,其中:

  • \((x,y)\)是当前正在考虑的位置。
  • \(S\)是覆盖格子的集合,可以压成一个整数。

时间复杂度\(O(2^{nm}nm)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 25
using namespace std;
int n,m,a[N][N],ans;
bitset<1<<20> f[N];
inline int toint(int x,int y){return (x-1)*m+(y-1);}
void dfs(int x,int y,int sta,int sum){
if(y>m) y-=m,x++;
if(x>n){ans=max(ans,sum);return;}
if(f[toint(x,y)][sta]) return;
f[toint(x,y)][sta]=1;
if(!((sta>>toint(x,y))&1)){
dfs(x,y+1,sta,sum);
sta^=(1<<toint(x,y)),sum^=a[x][y];
if(y<m&&!((sta>>toint(x,y+1))&1)) dfs(x,y+1,sta^(1ll<<toint(x,y+1)),sum^a[x][y+1]);
if(x<n&&!((sta>>toint(x+1,y))&1)) dfs(x,y+1,sta^(1ll<<toint(x+1,y)),sum^a[x+1][y]);
}else dfs(x,y+1,sta,sum);
}
signed main(){
cin>>n>>m;
int X=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j],X^=a[i][j];
}
}
dfs(1,1,0,X);
cout<<ans<<"\n";
return 0;
}

E - Most Valuable Parentheses

一个括号序列是合法的,当且仅当:

  • 对于奇数\(i\),长度为\(i\)的前缀至少有\(\lceil \frac{i}{2}\rceil\)个左括号。
  • 左括号数量\(=\)右括号数量。

所以遍历每个元素\(i\),如果\(i\)是奇数,就说明必须补充一个左括号。

这个左括号可以从前\(i\)个位置中还没放左括号的位置随意选择,用优先队列贪心即可。

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

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,ans;
priority_queue<int> q;
void solve(){
cin>>n;
for(int i=1,x;i<=2*n;i++){
cin>>x;
q.push(x);
if(i&1) ans+=q.top(),q.pop();
}
cout<<ans<<"\n";
ans=0;
while(!q.empty()) q.pop();
}
signed main(){
cin>>t;
while(t--) solve();
return 0;
}

F - Sums of Sliding Window Maximum

需要对\(k=1,2,\dots,n\)求解,所以思路大概有下面\(2\)种:

  • 递推求解。
  • 同时统计\(k\in[1,n]\)的答案。

前者没想出,后者就好考虑一些。

具体来说,对于\(a[i]\),考虑如下问题:

  • 给\(ans[1]\)的贡献是多少?

    —— 有多少个长度为\(1\)的区间以\(a[i]\)为最大值?
  • 给\(ans[2]\)的贡献是多少?

    —— 有多少个长度为\(2\)的区间以\(a[i]\)为最大值?
  • \(\dots\)

拿下图举个例子:

实际上通过举几个例子,不难发现,任何一个\(a[i]\)对\(ans[1],ans[2],\dots\)的贡献都可以写成形如这样的序列:

\[1,2,\dots,x-1,x,x,\dots,x,x-1,\dots,2,1
\]

(实际上还要\(\times a[i]\)再累加。)

其中:

  • 序列的总长度是\(R[i]-L[i]+1\)。

    • \(R[i]\)表示最大的\(j\ge i\)使得\(\max a[(i+1)\sim j]\le a[i]\)。
    • \(L[i]\)表示最小的\(j\le i\)使得\(\max a[j\sim (i-1)]<a[i]\)。
  • \(x=\min(R[i]-i,i-L[i])+1\)。

\(L,R\)的定义为什么是一个\(\le\)一个\(<\)?

  • 如果都是\(<\),则“\(a[i],a[j]\)同时为某区间的最大值”的情况会被忽略。
  • 如果都是\(\le\),则“\(a[i],a[j]\)同时为某区间的最大值”的情况会被统计\(2\)次。

这一串序列如果直接暴力累加到\(ans\)上,单次时间复杂度是\(O(n)\)的,无法接受。

但是不难发现上面序列的差分数组形如:

\[1,1,\dots,1,1,0,0,\dots,0,0,-1,-1,\dots,-1,-1
\]

再差分一下:

\[1,0,0,0,\dots,-1,0,0,0,\dots,-1,0,0,0,\dots,1
\]

所以直接修改这个双重差分数组即可。

最后对它求两次前缀和即可还原出\(ans\)数组。


至于怎么求\(L,R\),一开始写的是非常笨蛋的ST表+二分。时间复杂度\(O(n\log n)\)。

实际上用单调栈即可,见第\(2\)份代码。时间复杂度\(O(n)\)。

ST表+二分
#include<bits/stdc++.h>
#define int long long
#define N 200010
using namespace std;
int n,a[N],lg[N],maxx[N][25],sum[N];
void init(){
lg[0]=-1;
for(int i=1;i<=n;i++) lg[i]=lg[i/2]+1,maxx[i][0]=a[i];
for(int i=1;i<=lg[n];i++){
for(int j=1;j+(1<<i)-1<=n;j++){
maxx[j][i]=max(maxx[j][i-1],maxx[j+(1<<(i-1))][i-1]);
}
}
}
int maxr(int l,int r){
if(r<0||l>n||l>r) return INT_MIN;
int len=lg[r-l+1];
return max(maxx[l][len],maxx[r-(1<<len)+1][len]);
}
int findl(int R,int x){
int l=1,r=R;
while(l<r){
int mid=(l+r)>>1;
if(maxr(mid,R-1)<=x) r=mid;
else l=mid+1;
}
return l;
}
int findr(int L,int x){
int l=L,r=n;
while(l<r){
int mid=(l+r+1)>>1;
if(maxr(L+1,mid)<x) l=mid;
else r=mid-1;
}
return l;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
init();
for(int i=1;i<=n;i++){
int l=findl(i,a[i]),r=findr(i,a[i]);
int siz=r-l+1,len=min(i-l,r-i)+1;
sum[1]+=a[i],sum[len+1]-=a[i];
sum[siz-len+2]-=a[i],sum[siz+2]+=a[i];
}
for(int i=1;i<=2;i++) for(int j=1;j<=n;j++) sum[j]+=sum[j-1];
for(int i=1;i<=n;i++) cout<<sum[i]<<"\n";
return 0;
}
单调栈
#include<bits/stdc++.h>
#define int long long
#define N 200010
using namespace std;
int n,a[N],st[N],top,l[N],r[N],sum[N];
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],l[i]=1,r[i]=n;
for(int i=1;i<=n;i++){
while(top&&a[st[top]]<a[i]) r[st[top--]]=i-1;
st[++top]=i;
}
top=0;
for(int i=n;i;i--){
while(top&&a[st[top]]<=a[i]) l[st[top--]]=i+1;
st[++top]=i;
}
for(int i=1;i<=n;i++){
int siz=r[i]-l[i]+1,len=min(i-l[i],r[i]-i)+1;
sum[1]+=a[i],sum[len+1]-=a[i];
sum[siz-len+2]-=a[i],sum[siz+2]+=a[i];
}
for(int i=1;i<=2;i++) for(int j=1;j<=n;j++) sum[j]+=sum[j-1];
for(int i=1;i<=n;i++) cout<<sum[i]<<"\n";
return 0;
}

[题解]AtCoder Beginner Contest 407(ABC407) 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. obs学习之1——概览

    先占个位置,未完待续... 最近需要用OBS来开发直播软件,特整理这个分类的学习教程,以记录遇到的各种问题.

  2. Krita的语言选项里没有中文

    sudo apt install krita-l10n 即可,

  3. 论文解读:Aging with GRACE: Lifelong Model Editing with Discrete Key-Value Adapters

      论文发表于人工智能顶会NeurIPS(原文链接).当前的模型编辑器会因多次编辑损害模型性能,提出用于连续编辑的通用检索适配器(General Retrieval Adapters for Cont ...

  4. Springboot笔记<4>@Autowired和@Resource的区别

    @Autowired和@Resource的区别 @Resource 有两个常用属性name.type,所以分4种情况 指定name和type:通过name找到唯一的bean,找不到抛出异常:如果typ ...

  5. DeepSeekMath -- GRPO

    Deepseek系列博客目录 Model 核心 Date DeepSeekLLM 探究LLM Scalling Law 2024.01 DeepSeekMath 提出GRPO 2024.04 Deep ...

  6. JVM 类加载过程与字节码执行深度解析

    在 Java 高级程序员面试中,类加载机制与字节码执行原理是 JVM 模块的核心考察点.本文从类加载生命周期.类加载器协作机制.字节码执行引擎及面试高频问题四个维度,结合 JVM 规范与 HotSpo ...

  7. react项目添加typescript类型定义文件 .d.ts

    最近用react + antd mobile + typescript开发项目,其中使用了rc-form这个包,可惜没有typescript版本,导致找不到类型定义. 一起来重温一下这个经典的错误. ...

  8. gyp verb check python checking for Python executable "python2" in the PATH - noda-sass安装的艰难之路。

    第一次安装出现如下错误: gyp verb check python checking for Python executable "python2" in the PATH gy ...

  9. List集合详解

    List集合是有序的,可重复的元素.里面每个元素都有索引,通过索引访问元素. List接口是Colletion的子接口,自然可以用里面的方法.额外的增加了通过索引访问集合元素的方法.如下 packag ...

  10. 如何识别SQL Server中需要添加索引的查询

    引言 在数据库性能优化中,索引是提升查询速度最有效的手段之一.然而,不恰当的索引会降低写操作性能并增加存储开销.作为DBA,我们经常面临这样的挑战:如何精准定位哪些查询真正需要添加索引? 本文将分享几 ...