场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!场上被 E 卡 50 min 结果赛后一分钟过 F!

A - 9x9

借助 scanf 可以轻松完成。

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int a,b;
int main(){
scanf("%dx%d",&a,&b);
cout<<a*b<<endl;
}

B - tcaF

发现 \(X\) 值不超过 \(3\times 10^{18}\),证明 \(N\) 的值不超过 \(50\),直接暴力枚举即可。

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
long long a,fac=1;
int main(){
cin>>a;
for(long long i=1;;i++){
fac*=i;
if(fac==a){
cout<<i<<endl;
return 0;
}
} }

C - Snake Queue

出题人都让我们用队列了,那就用队列吧。

我们用队列维护没有离开的蛇。

每加入一条蛇,计算它的头部到第一条加入操作的蛇的头部的距离,记第 \(i\) 条蛇的这个值为 \(s_i\),然后把它加进队尾。

每删除一条蛇,就让他从队头离开。

操作三实际上就是查询第 \(k\) 条没有离开的蛇到第 \(1\) 条没有离开的蛇之间的距离。如果队头的蛇是 \(l\),则他们头部之间的距离即为 \(s_{l+k-1}-s_l\)。

主要考察前缀和。

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N=3e5+10;
typedef long long ll;
ll s[N],l,r,n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
ll op,x;
scanf("%lld",&op);
if(op==1){
scanf("%lld",&x);
r++,s[r]=s[r-1]+x;
}else if(op==2){
l++;
}else if(op==3){
scanf("%lld",&x);
printf("%lld\n",s[l+x-1]-s[l]);
}
}
return 0;
}

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

D - Snake Queue

我们将圆等分成四部分,容易发现这四部分包含的方格个数都一样。所以我们只计算右上部分的,最后乘 \(4\) 即可。

将圆心所在的格子用 \((0,0)\) 表示,则格子 \((i,j)\) 被圆包含必须满足 \(\sqrt{(i+0.5)^2+(j+0.5)^2}\) 不超过 \(r\),前提是 \(i\ge 0,j\ge 0\),即这个格子右上角到圆心的距离不超过 \(r\),这里会有算重,但是先不管。

假设 \(i=0\) 的所有格子中,满足上述条件且最靠上的格子是 \((0,j_0)\),同理定义 \((1,j_1),(2,j_2)\dots\),容易发现,\(j_0\ge j_1\ge j_2\dots\),可以用双指针快速计算。

将答案乘四后,我们发现 \((0,y),(0,-y),(x,0),(-x,0)\dots\) 这样的格子都算了两遍,所以要减去。最后再将原点对答案的贡献加上,即可得出正确答案。

好像有通项公式。

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N=3e5+10;
long long ans,r,res;
double dist(double x,double y){
return x*x+y*y;
}
int main(){
cin>>r;
for(int i=0,j=r-1;i<r;i++){
while(dist(i+0.5,j+0.5)>r*r)j--;
if(i==0)res=j+1;
ans+=j+1;
}
cout<<ans*4-4*res+1<<endl;
return 0;
}

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

E - Square Price

又被 E 创思了。

本题笔者场上没写出来,所以没代码。思路由赛后热心谷民提供。

\(10^{100}\) 是为了告诉我们商品无穷多。

先将所有商品按照 \(P_i\) 排序,记第 \(i\) 种商品最优方案下会买 \(S_i\) 种。

我们思考这样一个买商品的过程:

每个商品用二元组 \((k,p)\) 表示,初始时第 \(i\) 个商品为 \((1,P_i)\),表示这个商品是第 \(k\) 次买,价格为 \(p\),则买下这个商品的费用为 \([(k+1)^2-k^2]p=(2k+1)p\)。

我们把所有决策插入堆中,然后取出当前费用最小的商品,将总费用加上 \((2k+1)p\) 后,将 \((k,p)\) 删除,插入 \((k+1,p)\),直到总费用超过 \(m\)。此时买下的商品数目即为最优方案,该算法时间复杂度 \(O(\sqrt{m}\log n)\),无法通过本题。

回顾 \(S_i,P_i\) 的定义,容易发现一个性质,\(S_1\ge S_2\ge S_3\dots\)。

同时,最优方案下,无论何时,都满足对于任意 \(i\le n-1\),\((S_i,P_i)\) 的费用小于 \((S_{i+1}+1,P_{i+1})\) 的费用,如果不是,那就让 \(i\) 少买一个,\(i+1\) 多买一个。

我们惊喜的发现,在这种约束下,只要确定了 \(S_1\),剩下的 \(n\) 个商品买多少唯一确定。且 \(S_1\) 越大,最后确定的购买方案的费用总和也越大。

这样做,只需二分 \(S_1\),然后确定剩下的序列,再判断这个方案总费用是否超标。

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

F - Rated Range

因为 E 写了 50 min,导致这道题没有时间调试,最后赛后光速过题。

设 \(f_i\) 表示初始时评分为 \(i\),打完 \(n\) 轮后评分为 \(f_i\)。

以第一个样例为例,初始时:

\(i\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(8\)
\(f_i\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(8\)

评分超过 \(8\) 的部分不展示。

其中,评分在 \(1\sim 5\) 的可以加评分,则:

\(i\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(8\)
\(f_i\) \(2\) \(3\) \(4\) \(5\) \(6\) \(6\) \(7\) \(8\)

第二轮:评分 \(1\sim 3\) 的可以加评分:

\(i\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(8\)
\(f_i\) \(3\) \(4\) \(4\) \(5\) \(6\) \(6\) \(7\) \(8\)

第三轮:评分 \(3\sim 6\) 的可以加评分:

\(i\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(8\)
\(f_i\) \(4\) \(5\) \(5\) \(6\) \(7\) \(6\) \(7\) \(8\)

剩下几轮可以自己手摸。

容易发现,不管怎么打公开赛,\(f\) 数组始终单调不下降。

证明很简单,假设存在某个位置 \(i\),\(f_i>f_{i+1}\),则一定存在某一时刻:\(f_i=f_{i+1}\),然后打了一场比赛,\(f_i\) 评分增加,\(f_{i+1}\) 没有变化,但是 \(f_{i}=f_{i+1}\),两者评分应当同时增加,所以这种情况不存在。

这样就好办多了。用线段树维护 \(f\),假设某一场公开赛,等级分在 \([l,r]\) 内的可以加评分,因为 \(f\) 单调不减,用线段树二分二分出第一个满足 \(f_i\ge l\) 的位置 \(L\),和最后一个满足 \(f_i\le r\) 的位置 \(R\),实际上后者就相当于第一个满足 \(f_i\ge r\) 的位置的前一个位置。

加评分就是区间加,用懒标记维护。最后处理询问 \(x\) 时,直接查询 \(f_x\) 的值即可。

点击查看代码
#include <iostream>
#define ls (p<<1)
#define rs (p<<1|1)
using namespace std;
const int M=5e5+10,inf=0x3f3f3f3f;
int mx[M<<2],tag[M<<2],n,q,x;
void push_up(int p){
mx[p]=max(mx[ls],mx[rs]);
}
void push_down(int p){
if(!tag[p])return;
tag[ls]+=tag[p],mx[ls]+=tag[p];
tag[rs]+=tag[p],mx[rs]+=tag[p];
tag[p]=0;return;
}
void add(int p,int l,int r,int L,int R){
if(L<=l&&r<=R){
tag[p]++,mx[p]++;
}else{
push_down(p);int mid=(l+r)>>1;
if(L<=mid)add(ls,l,mid,L,R);
if(R>mid)add(rs,mid+1,r,L,R);
push_up(p);
}
}
int ask(int p,int l,int r,int x){
if(l==r)return l;
push_down(p);int mid=(l+r)>>1,ans;
if(mx[ls]>=x)ans=ask(ls,l,mid,x);
else if(mx[rs]>=x)ans=ask(rs,mid+1,r,x);
push_up(p);return ans;
}
void build(int p,int l,int r){
mx[p]=r;if(l==r)return;
int mid=(l+r)>>1;
build(ls,l,mid),build(rs,mid+1,r);
push_up(p);return;
}
int qry(int p,int l,int r,int x){
if(l==r)return mx[p];
push_down(p);int mid=(l+r)>>1;
if(x<=mid)return qry(ls,l,mid,x);
if(x>mid)return qry(rs,mid+1,r,x);
}
int main(){
scanf("%d",&n);
build(1,1,500001);//因为查询r+1可能超过 500000,所以要加1,因为这一点场上被创思了
for(int i=1;i<=n;i++){
int l,r;
scanf("%d %d",&l,&r);
int L=ask(1,1,500001,l);
int R=ask(1,1,500001,r+1)-1;
if(L<=R)add(1,1,500001,L,R);
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
int x;
scanf("%d",&x);
printf("%d\n",qry(1,1,500001,x));
}
return 0;
}

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

G - Odd Even Graph

看 都 没 看。

还是太菜了呜呜呜。

随机推荐

  1. 在 .NET 中的 ConvertAll 和 Select 方法哪个性能好

    .NET 的 List 中提供了 ConvertAll 和 Select 两个方法,在开发中实际上应该使用哪一个? 接下来通过基准测试脚本来对比性能. 先编写基准测试脚本: [MemoryDiagno ...

  2. MaxKB中如何选择向量模型?

    MaxKB内置的向量模型不足? 在MaxKB中知识文档Emdeding是很重要的一环,而这个过程就必须依赖向量模型.目前MaxKB内置的向量模型为text2vec-base-Chinese,一个针对中 ...

  3. windows快速开启【程序和功能】

    程序和功能一般常用的操作是对软件进行卸载. 方式一: 1. Win+R打开运行 2. 输入appwiz.cpl命令 方式二: 1.Win+X打开快捷开关 2. F进去应用和功能 3.点击右侧程序和功能 ...

  4. 信息资源管理文字题之“IT服务管理的核心流程和具体内容”

    一.为了充分利用ERP信息系统资源,LX集团采用了各种先进的信息系统管理概念和方法,包括IT服务管理. 要求:说明IT服务管理流程包括那两大核心类别,分别说明他们个包含哪些具体流程 二.答案 答:两大 ...

  5. vue3 基础-列表渲染

    本篇讲列表渲染, 主要是对 v-on 指令配合 v-if 和一些数组相关的方法来体验 vue 的模板渲染方法. 数组元素的渲染 <!DOCTYPE html> <html lang= ...

  6. vue3 基础-data-methods-computed-watch

    本篇来简单了解 vue 的数据, 方法, 计算属性和监听器等相关内容. data ( ) vue 里面的 data ( ) 函数返回一些能供模板 template 直接使用的数据, 以变量的方式进行 ...

  7. 462.Minimum Moves to Equal Array Elements II——LeetCode进阶路

    原题链接https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/ 题目描述 Given a non-empty i ...

  8. Github Copilot 实战: 从零开始用AI写一个OCR工具 (1)

    最近AI很火,咱也尝试一下由浅入深探索一下 Github Copilot 的能力和底限. 使用的环境是 Windows11 + Microsoft Visual Studio Enterprise 2 ...

  9. RL之深夜有感

    世界似乎就是一个巨大的强化学习环境(Env),身处其中的每个人就是里面的智能体,有的为生计四处奔波:有的要探寻精神上的欢娱:有的似乎想跳出Env,不想再继续下去了:可以说每个人的target都不尽相同 ...

  10. 来公司 3 年,被新来的技术大佬 PUA 了。。。

    大家好,我是程序员鱼皮.最近收到一位鱼友的求助,感觉很有代表性,相信很多技术人都会遇到类似的情况.今天就和大家聊聊这个话题,看看遇到这种情况该怎么办. 鱼友提问 鱼皮哥,求解惑!最近我们公司新来了一个 ...