T1 [JZOJ4879] 少女觉

题目描述

  “在幽暗的地灵殿中,居住着一位少女,名为古明地觉。”

  “据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力——读心。”

  “掌控人心者,可控天下。”

  人的记忆可以被描述为一个黑块(B)与白块(W)的序列,其中情感值被定义为序列中黑块数量与白块数量之比。

  小五口在发动读心术时,首先要解析人的记忆序列,因此,需要将序列分割为一些段,并且要求每一段记忆序列的情感值都相等。

  下面给出两个例子:

  BWWWBB -> BW + WWBB (Ratio=1:1)

  WWWBBBWWWWWWWWWB -> WWWB + BBWWWWWW + WWWB (Ratio=3:1)

  现在小五手上有一个人的记忆序列,她想要知道,如何将手中的记忆序列分成尽可能多的段呢?

数据范围

  对于 $10 \%$ 的数据,$N \leq 15$

  对于 $20 \%$ 的数据,$N \leq 500$

  另有 $30 \%$ 的数据,$K=1$

  另有 $30 \%$ 的数据,$K \leq 50$

  对于 $100 \%$ 的数据,$N \leq 10^5$,序列长度不超过 $10^9$

分析

  显然每段序列的黑白块之比都等于总序列的黑白块之比

  所以只要在每加入一段相同颜色的连续方块时,判断是否能组成一段新的合法序列

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100005int T, n, ans;
int s[N][2], sum[2], last[2];
char c;int gcd(int a,int b) {return !b ? a : gcd(b, a % b);
}int main() {freopen("silly.in", "r", stdin);freopen("silly.out", "w", stdout);scanf("%d", &T);while (T--) {ans = sum[0] = sum[1] = last[0] = last[1] = 0;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d %c", &s[i][1], &c);if (c == 'B') s[i][0] = 0, sum[0] += s[i][1];if (c == 'W') s[i][0] = 1, sum[1] += s[i][1];}if (!sum[0]) {printf("%d\n", sum[1]); continue;}if (!sum[1]) {printf("%d\n", sum[0]); continue;}int g = gcd(sum[0], sum[1]);sum[0] /= g; sum[1] /= g;for (int i = 1; i <= n; i++) {int now = s[i][0];if (!last[now ^ 1] || last[now ^ 1] % sum[now ^ 1]) {last[now] += s[i][1]; continue;}int need = last[now ^ 1] / sum[now ^ 1] * sum[now] - last[now];if (need < 0) last[now] += s[i][1];else if (s[i][1] < need) last[now] += s[i][1];else last[now] = s[i][1] - need, last[now ^ 1] = 0, ans++;}printf("%d\n", ans);}return 0;
}

View Code

T2 [JZOJ4883] 灵知的太阳信仰

题目描述

  “在炽热的核熔炉中,居住着一位少女,名为灵乌路空。”

  “据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量——核能。”

  “核焰,可融真金。”

  每次核融的时候,空都会选取一些原子,排成一列。然后,她会将原子序列分成一些段,并将每段进行一次核融。

  一个原子有两个属性:质子数和中子数。

  每一段需要满足以下条件:

  1、同种元素会发生相互排斥,因此,同一段中不能存在两个质子数相同的原子。

  2、核融时,空需要对一段原子加以防护,防护罩的数值等于这段中最大的中子数。换句话说,如果这段原子的中子数最大为x,那么空需要付出x的代价建立防护罩。求核融整个原子序列的最小代价和。

数据范围

  对于 $20\%$ 的数据,$1 \leq N \leq 100$

  对于 $40\%$ 的数据,$1 \leq N \leq 1000$

  对于 $100\%$ 的数据,$1 \leq N \leq 10^5$

分析

  考场上的想法是记录每个数作为区间末端时可以达到的区间最前端,用 $ST$ 表维护区间最大值,然后在可行范围内枚举断点 $DP$ 得到答案

  这样的做法是 $O(n^2)$ 的,所以考虑在枚举断点时如何优化

  我们发现每个位置的 $f$ 值只可能从中子数大于等于自身的位置的前一个原子或者是可以达到的最前端位置的前一个原子处转移过来,所以可以维护一个中子数非严格递减的单调队列,将队列中的每个位置对应的答案放入 $set$ 中,这样就便于插入删除元素和查找最小值,操作时间复杂度 $O(log \; n)$

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100005int n, l = 1, r = 0;
int a[N], b[N], pos[N], pre[N];
int f[N], q[N], p[N];
multiset<int> s;int main() {freopen("array.in", "r", stdin);freopen("array.out", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d%d", a + i, b + i);pre[i] = max(pre[i - 1], pos[a[i]] + 1);pos[a[i]] = i;}memset(f, 0x3f, sizeof f); f[0] = 0;for (int i = 1; i <= n; i++) {while (l <= r && p[l] < pre[i]) s.erase(q[l]), l++;while (l <= r && b[p[r]] < b[i]) s.erase(q[r]), r--;p[++r] = i; q[r] = f[p[r - 1]] + b[i]; s.insert(q[r]);s.erase(q[l]); s.insert(q[l] = f[pre[i] - 1] + b[p[l]]);f[i] = *s.begin();}printf("%d\n", f[n]);return 0;
}

View Code

T3 [JZOJ4882] 多段线性函数

题目描述

数据范围

分析

  通过人类智慧发现,$f_{min}(y)$ 是一个单峰函数,所以可以三分查找

  但是,这题有一个优美的解法,就是把所有端点一起排序后取中间两个点为答案

  同时,我有一个通俗易懂的证明

  对于该答案区间,区间左右两侧的点数量一定相同

  而题目中所给的所有区间,与答案区间一共有三种关系,分别是在答案区间左侧,在答案区间右侧,和包含答案区间

  由于包含答案区间的区间的两端点一定分别在答案区间两侧,所以对两侧点数量关系没有影响

  所以剩下的点一定是在答案区间左/右侧的区间的端点

  这就很显然了,左右两侧的区间数量一定是相等的

  对于一个动点,如果两侧区间数相等,那么它到所有区间的距离之和一定是不变的

  当它向一侧不断移动时,与移动方向相同的一侧的区间数减少,反方向一侧的区间数增多,那么它到所有区间的距离之和是在不断变大的

  所以,中间两点组成的区间一定是答案最优的区间

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100005int n;
int p[2 * N];int main() {freopen("linear.in", "r", stdin);freopen("linear.out", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%d%d", p + (i << 1) - 1, p + (i << 1));sort(p + 1, p + (n << 1) + 1);printf("%d %d\n", p[n], p[n + 1]);return 0;
}

View Code

T4 [JZOJ3430] DY引擎

题目描述

  BOSS送给小唐一辆车。小唐开着这辆车从PKU出发去ZJU上课了。

  众所周知,天朝公路的收费站超多的。经过观察地图,小唐发现从PKU出发到ZJU的所有路径只会有N个不同的中转点,其中有M个点是天朝的收费站。N个中转点标号为1…N,其中1代表PKU,N代表ZJU。中转点之间总共有E条双向边连接。

  每个点还有一个附加属性,用0/1标记,0代表普通中转点,1代表收费站。当然,天朝的地图上面是不会直接告诉你第i个点是普通中转点还是收费站的。地图上有P个提示,用[u, v, t]表示:[u, v]区间的所有中转点中,至少有t个收费站。数据保证由所有提示得到的每个点的属性是唯一的。

  车既然是BOSS送的,自然非比寻常了。车子使用了世界上最先进的DaxiaYayamao引擎,简称DY引擎。DY引擎可以让车子从U瞬间转移到V,只要U和V的距离不超过L,并且U和V之间不能有收费站(小唐良民一枚,所以要是经过收费站就会停下来交完钱再走)。

  DY引擎果然是好东西,但是可惜引擎最多只能用K次。

  小唐想知道从PZU开到ZJU用的最短距离(瞬间转移距离当然是按0来计算的)。

数据范围

  对于 $30\%$ 的数据,$2 \leq N \leq 30$,$max(0,N-10) \leq M \leq N$,$0 \leq K \leq 10$

  对于 $100\%$ 的数据,$2 \leq N \leq 300$,$max(0,N-100) \leq M \leq N$,$E \leq 5 \times 10^4$,$1 \leq P \leq 3 \times 10^3$,$1 \leq L \leq 10^6$,$0 \leq K \leq 30$

分析

  B组题难度果然有所提高啊 还有这个D(a)Y(a)??

  这题一共分为两个部分,一个是找出所有收费站的位置连这种信息都不给我感到很遗憾,一个是找出最短路

  首先题目给定了某两个站点间的收费站数量,这相当于一个差分约束系统

  设 $s[i]$ 为从源点到 $i$ 之间的收费站数量,对于每个条件 $[u,v,t]$,有 $s[v]-s[u-1] \geq t$,即 $s[u-1]-s[v] \leq -t$

  同时还有一些隐含条件 $s[i]-s[i-1] \geq 0$,即 $s[i-1]-s[i] \leq 0$;$s[i]-s[i-1] \leq 1$

  对于每个形如 $v-u \leq w$ 的不等式,就连一条由 $u$ 指向 $v$ 权值为 $w$ 的有向边,然后在图上跑一边 $spfa$

  最后得到的 $s[i]-s[i-1]$ 若等于 $1$ ,则说明 $i$ 位置上为收费站,否则为普通中转站

  然后在原图上用 $floyd$ 处理出所有点之间不经过收费站的最短路,再把图分为 $K+1$ 层,在相邻两层图之间把最短路小于等于 $L$ 的两点用边权为 $0$ 的有向边连起来,最后用 $spfa$ 找出 $1$ 到 $n$ 的最短路即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 302
#define M 50002
#define K 32int n, m, e, p, l, t, tot, ans = inf;
int to[(M << 1) * K], len[(M << 1) * K], nxt[(M << 1) * K], head[N * K];
int edge[M][3], f[N][N], dis[N * K], vis[N * K];void add(int u, int v, int w) {to[++tot] = v; len[tot] = w;nxt[tot] = head[u]; head[u] = tot;
}void spfa(int x, int y) {memset(dis, 0x3f, sizeof dis);memset(vis, 0, sizeof vis);queue<int> q;dis[x] = y; q.push(x);while (!q.empty()) {int now = q.front(); q.pop(); vis[now] = 0;for (int i = head[now]; i; i = nxt[i])if (dis[to[i]] > dis[now] + len[i]) {dis[to[i]] = dis[now] + len[i];if (!vis[to[i]]) {vis[to[i]] = 1; q.push(to[i]);}}}
}void floyd() {for (int k = 1; k <= n; k++)if (!(dis[k] - dis[k - 1]))for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (i != j && i != k && j != k)f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}int main() {scanf("%d%d%d%d%d%d", &n, &m, &e, &p, &l, &t);memset(f, 0x3f, sizeof f);for (int i = 1; i <= e; i++) {int u, v, w;scanf("%d%d%d", &u, &v, &w);edge[i][0] = u; edge[i][1] = v; edge[i][2] = w;f[u][v] = f[v][u] = min(f[u][v], w);}for (int i = 1; i <= p; i++) {int u, v, w;scanf("%d%d%d", &u, &v, &w);add(v, u - 1, -w);}for (int i = 2; i <= n; i++)add(i, i - 1, 0), add(i - 1, i, 1);spfa(n, m); floyd();memset(head, 0, sizeof head); tot = 0;for (int i = 1; i <= e; i++)for (int k = 0; k <= t; k++) {add(k * n + edge[i][0], k * n + edge[i][1], edge[i][2]);add(k * n + edge[i][1], k * n + edge[i][0], edge[i][2]);}for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (i != j && f[i][j] <= l)for (int k = 0; k < t; k++)add(k * n + i, (k + 1) * n + j, 0);spfa(1, 0);for (int k = 0; k <= t; k++)ans = min(ans, dis[k * n + n]);printf("%d\n", ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/Pedesis/p/11342279.html

2019-08-12 纪中NOIP模拟赛B组相关推荐

  1. 2019-08-01 纪中NOIP模拟赛B组

    T1 [JZOJ2642] 游戏 题目描述 Alice和Bob在玩一个游戏,游戏是在一个N*N的矩阵上进行的,每个格子上都有一个正整数.当轮到Alice/Bob时,他/她可以选择最后一列或最后一行,并 ...

  2. 【题解】少女觉 (2019.08.12纪中【NOIP提高组】模拟 B 组T1)贪心

    题目来源:中山纪念中学 题目描述: 在幽暗的地灵殿中,居住着一位少女,名为古明地觉. 据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力--读心. 掌控人心者,可控天下. 咳咳. 人的 ...

  3. 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary

    纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...

  4. 纪中集训2020.01.16【NOIP普及组】模拟赛C组总结+【0.Matrix】分析

    纪中集训2020.01.16[NOIP普及组]模拟赛C组总结+[0.Matrix]分析 题目: 0.matrix 1.product 2.binary 3.value 巨佬估分:100+100+40+ ...

  5. NOIP模拟赛csy2021/10/30

    NOIP模拟赛csy2021/10/30 比赛时间规划 赛后反思与总结 这..总的来说感觉打的很不好,根本没有状态,有一部分原因是今天来晚了,太慌,更多的还是这次题感觉很难o(╥﹏╥)o 比赛时间规划 ...

  6. JZOJ(中山纪念中学) 2018.02.02【NOIP普及组】模拟赛D组

    本次题目:2018.02.02[NOIP普及组]模拟赛D组 第一题 题目:第一题 公牛数字 题意: 求题目给出两个数字的乘积 分析: 这题明显只是考察学生的高精可我居然没做对,只要多练习几次,即可AC ...

  7. 辣鸡(ljh) NOIP模拟赛 模拟 平面几何 数论 化学相关(雾)

    [题目描述] 辣鸡ljhNOI之后就退役了,然后就滚去学文化课了. 然而在上化学课的时候,数学和化学都不好的ljh却被一道简单题难住了,受到了大佬的嘲笑. 题目描述是这样的:在一个二维平面上有一层水分 ...

  8. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  9. NOIP 模拟赛 长寿花 题解

    NOIP 模拟赛 长寿花 题解 要放 \(n\) 层物品,第 \(i\) 层有 \(a_i\) 个位置放物品,物品有 \(m\) 中颜色,有约束条件: 同一层两个相邻物品颜色不能相同. 相邻两层颜色集 ...

最新文章

  1. JVM结构、GC工作机制详解
  2. java filesystem 追加_java 如何往已经存在的excel表格里面追加数据的方法
  3. 机器学习实战读书笔记--logistic回归
  4. mysql组件化_组件化开发和模块化开发概念辨析
  5. java.util.NoSuchElementException: Unable to validate object
  6. 石家庄市职称计算机,河北石家庄2010年职称计算机考试报名通知
  7. 100阶乘末尾有多少个零
  8. cks32和stm32_cks子,间谍,局部Mo子和短管
  9. eclipse中下载spring-tool-suite插件遇到的问题
  10. RabbitMQ 高可用之镜像队列
  11. 2287: 【POJ Challenge】消失之物
  12. linux chmod、chown命令不起作用
  13. PV、EV、AC、BAC、EAC、ETC等的含义及计算公式
  14. 大一新生 电脑小白如何选择电脑 电脑知识全面讲解
  15. android 移除子view,android-从父视图中移除视图与隐藏视图
  16. vue报错:Not Found - GET https://registry.npmjs.org/- Not found
  17. 腾讯T9级到底需要什么样的技术水平?我们又该如何学习?
  18. html在线编辑器合并单元格,Bootstrap实现的表格合并单元格示例
  19. POJ1659 Frogs' Neighborhood(Havel定理)
  20. EventBus报错:and its super classes have no public methods with the @Subscribe annotation

热门文章

  1. 解决电脑C盘空间不足,发现微信和qq文件占用了大量内存
  2. java swing 自动补全_扩展easyui的combobox组件的自动完成(autocomplete)
  3. 【spark实训】-- Scala实现单词计数
  4. 手把手教你撸一个泡妞神奇
  5. salmon:sailfish的升级版本
  6. 计算机关机键消失了,电脑关机键不见了,没有了关机按钮怎么办
  7. SII9136 调试出来, 欣喜若狂!(需要 SII9136 资料的请联系我!)
  8. HarmonyOS与Android的全面对比
  9. c语言入门经典doc,C语言入门经典C语言编程.ppt
  10. AE 学习笔记(一)