7.16模拟赛总结

  • 总述
  • 题目详情
    • T1 取餐号
    • T2 堆人塔
    • T3 钦定IOI选手
      • 20pts做法
      • 100pts做法
    • T4 攻打恶魔之巅
      • 水水版DP
    • T5 抉择

暑假集训模拟赛Day1

总述

真想不到,我们普转提竟与提高组同一套题目!!!
本场比赛:

  • 满分 500pts500pts500pts
  • 得分325pts325pts325pts
  • RankRankRank 555
  • RatingRatingRating +86+86+86

能打成这样已经超出我的意料了,这个成绩也是有很大水分的。肯定不是因为数据太水了……

题目详情

看来PDFPDFPDF类型的题目是传不进csdncsdncsdn里了……

T1 取餐号


这道题无需多言,简单的埃氏筛即可ACACAC。但是我为什么要花费大量精力去记一个不是最优的算法呢??

//欧拉筛代码
void Prime() {for(int i = 2; i <= n; i ++) {if(!v[i]) {v[i] = i;prime[++ len] = i;}for(int j = 1; j <= len; j ++) {if(prime[j] > v[i] || prime[j] > n / i) break;v[i * prime[j]] = prime[j];}}
}

喜提100pts100pts100pts

T2 堆人塔


这道题题意很容易就能搞明白:每次凭借区间中最大值将区间分为两个小区间,再分别不断取最大值、划分小区间……
显然是一道经典的递归题目。但是如果暴力去求每个区间的最大值显然是不行的,所以我们需要使用STSTST表或线段树进行优化。因为本蒟蒻不会线段树,在此给出ST表代码

void Get_ST() {for(int i = 1; i <= n; i ++)t[0][i].num = a[i], t[0][i].locat = i;int T = log2(n) + 1;for(int i = 1; i <= T; i ++)for(int j = 1; j <= n - (1 << i) + 1; j ++) {my_str2 x, y;x = t[i - 1][j], y = t[i - 1][j + (1 << (i - 1))];if(x.num < y.num) t[i][j] = y;else t[i][j] = x;}
}int Find(int x, int y) {int len = y - x + 1;len = log2(len);if(t[len][x].num > t[len][y - (1 << len) + 1].num) return t[len][x].locat;else return t[len][y - (1 << len) + 1].locat;
}void dfs_1(int dep, int l, int r) {if(l > r) return ;int loc = Find(l, r);b[loc] = dep;if(loc == l) dfs_1(dep + 1, l + 1, r);else if(loc == r) dfs_1(dep + 1, l, r - 1);else {dfs_1(dep + 1, l, loc - 1);dfs_1(dep + 1, loc + 1, r);}return ;
}

喜提100pts100pts100pts

题外话: 某个神仙同学czlczlczl在没学笛卡尔树的情况下,考场上用单调栈切掉本题,而他的代码正是笛卡尔树的代码。

//czl神的代码(注释均为czl本人注释)
#include<bits/stdc++.h>//貌似要做单调栈?   每个数都是它左边或右边第一个大于它的儿子(取小的)
using namespace std;
const int N = 1e5 + 10;
int n, a[N], cnt[N], L[N], R[N], head[N], tot, st;
stack< int > s;
struct edge{int v, last;
}E[N * 2];
void Get(){for(int i = 1; i <= n; i++){ L[i] = R[i] = 1e6;} for(int i = 1; i <= n; i++){//找每个数的两边第一个大于它的数 while(!s.empty() && a[i] > a[s.top()]){int t = s.top();R[t] = i;//右边第一个比它大的s.pop(); }if(!s.empty()){int t = s.top();L[i] = t;//左边第一个比他大的 }s.push(i);}
}
void add(int u, int v){E[++tot].v = v;E[tot].last = head[u];head[u] = tot;
}
void dfs(int s){for(int i = head[s]; i != 0; i = E[i].last){int v = E[i].v;cnt[v] = cnt[s] + 1;dfs(v);}
}
int main(){freopen("tower.in", "r", stdin);freopen("tower.out", "w", stdout);scanf("%d", &n);for(int i = 1; i <= n; i++)scanf("%d", &a[i]);Get(); for(int i = 1; i <= n; i++){//建图 int l_max = L[i], r_max = R[i], f = 0; //L[i], R[i]分别表示左右两边比第i个数大的数 if(l_max == 1e6 && r_max == 1e6) st = i;else{if(l_max == 1e6) add(r_max, i);else if(r_max == 1e6) add(l_max, i);else{if(a[l_max] > a[r_max]) add(r_max, i);else add(l_max, i);}}}dfs(st); for(int i = 1; i <= n; i++){if(i == 1) printf("%d", cnt[i]);else printf(" %d", cnt[i]);}printf("\n");return 0;
}
/*
7
1 3 2 7 5 6 4
*/

膜拜大佬……

T3 钦定IOI选手

20pts做法

本题很显然是让我们维护一个动态中位数,所以很显然就能想到对顶堆。

#define p_q priority_queue
p_q < int , vector < int > , less < int > > qq1;//大根堆,堆顶存中位数
p_q < int , vector < int > , greater < int > > qq2;//小根堆
int ans = -1;
for(int l = 1; l <= n - k + 1; l ++) {//左端点qq1.push(a[l]);for(int r = l + 1; r <= n; r ++) {//右端点if(a[r] > qq1.top()) qq2.push(a[r]);else qq1.push(a[r]);int len = r - l + 1;while(qq1.size() > (len + 1) / 2) {qq2.push(qq1.top());qq1.pop();}while(qq1.size() < (len + 1) / 2) {qq1.push(qq2.top());qq2.pop();}if(len >= k) ans = max(ans, qq1.top());}while(!qq1.empty()) qq1.pop();while(!qq2.empty()) qq2.pop();
}
printf("%d", ans);

但很显然,它的时间复杂度是O(n2logn)O(n^2log~n)O(n2log n)的,无法ACACAC。

100pts做法

看到中位数,显然与数的绝对大小无关,只与相对大小有关。考虑将每个数进行一些转化。对于一个数xxx
,容易想到将≤x\le x≤x 的都改为−1-1−1,>x>x>x 的都改为111,得到新数列(这里称作bib_ibi​)。此时便有一个结
论:对于区间 [l,r][l, r][l,r],如果满足 ∑i=1nbi>0\sum \limits_{i = 1}^{n} b_i >0i=1∑n​bi​>0,则 [l,r][l, r][l,r]的中位数必定 ≥x\ge x≥x(可以从与xxx的相对
大小角度想)。

因此考虑每次二分xxx,记录bbb数组的前缀和和前缀最小值,在区间长度≥k\ge k≥k时差分计算一下即可。

bool check(int x) {for(int i = 1; i <= n; i ++) {if(a[i] >= x) b[i] = 1;else b[i] = -1;sum[i] = sum[i - 1] + b[i];}int minn = 1e9;for(int i = k; i <= n; i ++) {minn = min(minn, sum[i - k]);//前缀最小值if(sum[i] - minn > 0) return 1;//只要区间和大于0,那么x就有可能成为此区间的中位数}return 0;
}

怒提20pts20pts20pts

T4 攻打恶魔之巅


这道题刚拿到就觉得是个DPDPDP。关于这个DPDPDP,我写挂了,但没完全写挂。

水水版DP

这道题的DPDPDP状态设置很容易就能想到:dpi,jdp_{i,j}dpi,j​表示走了iii步,花费了jjj个魔法石以后的最小体力。这显然是以魔法石的数量来划分的阶,所以应把第二维的循环放在最外层,这样才能避免后效性。~~但是我没想到,就给他放到了最内层……~~另外,为了得到最优情况,我们还要正反各来一遍。具体原因见下图:

在这种情况下,最优解是:从111走一步到333,然后花一颗魔法石到888,接着往回跳到666,再使用第二颗魔法石到终点。但是如果不往后跳,是无法在两步以内到终点的。但是我没想到,只正着跑了……

由此可见,此题细节之多,数据之水。
ACACAC代码:

#include<bits/stdc++.h>
using namespace std;const int maxn = 5e5 + 5;
int n, m, c;
int t[maxn];
int dp[maxn][23];int main() {scanf("%d%d%d", &n, &m, &c);for(int i = 1; i <= n; i ++) scanf("%d", &t[i]);memset(dp, 0x7f, sizeof dp);dp[1][0] = 0;for(int k = 0; k <= c; k ++) {for(int i = 1; i <= n; i ++) {for(int j = 1; j <= m; j ++) {if(i + j <= n) dp[i + j][k] = min(dp[i + j][k], dp[i][k] + 1);if(k < c) dp[t[i]][k + 1] = min(dp[i][k], dp[t[i]][k + 1]);}}for(int i = n; i >= 1; i --) {for(int j = 1; j <= m; j ++) {if(i - j >= 1) dp[i - j][k] = min(dp[i - j][k], dp[i][k] + 1);if(k < c) dp[t[i]][k + 1] = min(dp[i][k], dp[t[i]][k + 1]);}}}int ans = 0x7f7f7f7f;for(int k = 0; k <= c; k ++)ans = min(ans, dp[n][k]);printf("%d", ans);return 0;
}

侥幸提95pts95pts95pts

T5 抉择

本题不在本蒟蒻的知识范围内……

2022.07.16模拟赛总结相关推荐

  1. 2021.7.16模拟赛C组总结(转载XJY)

    2021.7.16模拟赛C组总结 这次比赛,题虽然不难,但丝毫不影响我打挂-唉- 0+100+50+0=150 题解 T1 题目描述: ​ 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小 ...

  2. 长沙学院2022蓝桥杯模拟赛一

    长沙学院2022蓝桥杯模拟赛一_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJhttps://ac.nowcoder.com/acm/contest/26010#ques ...

  3. 【8.16模拟赛.7235】【洛谷P7413】[USACO21FEB] Stone Game G【博弈论】

    题目链接:https://www.luogu.com.cn/problem/P7413 分析 洛谷er,yyds 上代码 #include<iostream> #include<cs ...

  4. 11.16模拟赛总结

    打的平平无奇了属于是 又没休息好,不过今天注意力还算集中 时间安排 8.30-8.50 看一遍题 感觉T1是个签到 8.50-10.00 考虑了一下T1的实现 发现set不可后再线段树动态开点和vec ...

  5. tarjan+拓扑序+差分--2018.10.16模拟赛T2

    题目: 阿天住的城市有 n 个政府部门,这些部门之间用了 m 条有向路径 连接了起来.有趣的是,每过一天这些路径都会变换方向,也就是说, 偶数的日子和奇数的日子的图是不同的. 阿天在社保局工作,可惜他 ...

  6. 10.16模拟赛题解

    T1 Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋,成为了杰 ...

  7. 牛客网9.16模拟赛t1方差

    这题本不想写题解的,因为是极水的一道公式题 题目链接:方差 题目: 题意 一个长度为 m 的序列 b[1-m] ,我们定义它的方差为 ,其中 表示序列的平均值. 可以证明的是,如果序列元素均为整数,那 ...

  8. 2022-09-16 蒟蒻の模拟赛之Summary

    2022/09/16--模拟赛总结 自我感觉打的还可以,虽然还是没有拿到所有部分分,,不过比之前的要好,嗯. T1T1T1 由于电脑问题,打不开c++,所以抄了题之后重启了一下,然后机房电脑太拉胯,重 ...

  9. 2021.07.16【普及组】模拟赛C组

    2021.07.16[普及组]模拟赛C组 文章目录 2021.07.16[普及组]模拟赛C组 前言 花生采摘 题目 解析 代码 FBI树 题目 解析 代码 火星人 题目 解析 代码 麦森数 题目 解析 ...

最新文章

  1. 用户操作-用户添加操作代码实现
  2. spring的钩子_spring提供的钩子,你知道哪些
  3. jQuery选择器的效率问题
  4. 计算机图形学考试题及答案_计算机图形学考试题及答案
  5. mysql 导入 sqlite_Mysql 数据导入SQlite
  6. 机器学习术语中英对照表
  7. Ruby中的类与对象(一)
  8. hadoop ubantu环境搭建_创帆云大数据教程系列1-搭建基于docker的hadoop环境安装规划、容器通信及zookeeper...
  9. 带着身体在香港肤浅行走(一)
  10. 【适合程序员的代码笔记软件】Quiver 3.2.6 for Mac
  11. C语言运行机制(过程)简述
  12. 237Echarts - 3D 柱状图(Image to Bar3D)
  13. 在Java web页面使用ECharts制作图表
  14. 服务器U盘安装虚拟化,用Proxmox ISO镜像制作引导U盘
  15. 万能用户名和万能密码
  16. 安卓手机手电筒不见了?
  17. 技术科普丨景深到底是什么
  18. PDF 签章图片不显示问题
  19. Win7的不关闭防火墙下的FTP设置
  20. Python 打造基于百度翻译的命令行翻译工具

热门文章

  1. 5G组网和非独立组网
  2. 多线程下载王者农药高清壁纸
  3. Java学习day18-集合框架2(泛型,工具类,TreeMap)
  4. 硬件(esp32),服务器(python),前端,三端联调的电子琴项目,可以实现多种乐器奏乐。
  5. 如何做一个FPGA工程师
  6. 你是什么命,好玩的很
  7. 很火的华为太空表网站源码
  8. 摩托罗拉Z2硬改相机无人直播刷机教程
  9. equals和==的区别
  10. 计算并输出sin(x)、cos(x)、|x|、ex、xy的值