T1 [JZOJ1534] rank

题目描述

  小h和小R正在看之前的期末&三校联考成绩,小R看完成绩之后很伤心,共有n个学生,第i个学生有一个总成绩Xi,因为他的排名是倒数第k个,于是小R想知道那些成绩比他低(包括成绩和他一样)的同学的成绩,这样能让他没那么伤心。

数据范围

  $1 \leq N \leq 5 \times 10^6$,$0 \leq X \leq 10^5$

分析

  我以为我拿到了C组题,惊了

  数据量大数据值小,显然桶排序

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 5000005
#define M 100005 int n, k, x, mins = inf, maxs, s[M]; int main() {
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++) {
scanf("%d", &x); s[x]++;
mins = min(mins, x);
maxs = max(maxs, x);
}
int now = ;
for (int i = mins; i <= maxs; i++) {
while (s[i]--) {
if (++now > k) break;
printf("%d ", i);
}
if (now >= k) break;
} return ;
}

T2 [JZOJ1536] seek

题目描述

  俗话说“好命不如好名”,小h准备给他的宠物狗起个新的名字,于是他把一些英文的名字全抄下来了,写成一行长长的字符串,小h觉得一个名字如果是好名字,那么这个名字在这个串中既是前缀,又是后缀,即是这个名字从前面开始可以匹配,从后面开始也可以匹配,例如abc在abcddabc中既是前缀,也是后缀,而ab就不是,可是长长的字符让小h几乎昏过去了,为了给自己的小狗起个好名字,小h向你求救,并且他要求要将所有的好名字的长度都输出来。

数据范围

  $1 \leq \vert S \vert \leq 4 \times 10^5$

分析

  这题主要是考对 $KMP$ 算法的理解

  事实上这里只需要用到 $KMP$ 中的 $nxt$ 数组,即字符串每个前缀区间的前后缀最长匹配(不包含自身)

  首先原字符串肯定是符合题意的,而对于每个合法的区间,它的最长匹配前缀区间也是合法的

  所以只需要在求出 $nxt$ 数组后,依次输出所有合法区间就可以了

  当然这题用 $Hash$ 来做也是很简单的

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 400005 char s[N];
int nxt[N]; void find(int x) {
if (!x) return;
find(nxt[x]);
printf("%d ", x);
} int main() {
scanf("%s", s + );
int n = strlen(s + );
for (int i = , j = ; i <= n; i++) {
while (j && s[j + ] != s[i]) j = nxt[j];
if (s[j + ] == s[i]) j++;
nxt[i] = j;
}
find(n); return ;
}

T3 [JZOJ1537] pot

题目描述

  这个假期,小h在自家院子里种了许多花,它们围成了一个圈,从1..n编号,小h对每盆花都有一个喜好值xi,小h现在觉得这样一成不变很枯燥,于是他做了m个改动,每次把第ki盘花改成喜好值为di的花,然后小h要你告诉他,在这个花圈中,连续的最大喜好值是多少(不能整圈都选)。

数据范围

  $1 \leq N,M \leq 10^5$,$-10^3 \leq X \leq 10^3$

分析

  如果花盆是一条链的形状,那么这题就是一个很裸的线段树维护最大子区间和

  但是这是一个环,所以区间在左右端点处可能是连接着的

  我们发现穿过左右端点的最大子区间和,可以用区间和减去最小子区间来表示

  因此我们只需要再维护最小子区间和,最后在两者中取较大值

  还要注意不能整圈都取,即序列不含 $0$ 时最优解不能等于总区间和

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100005
#define lc (p << 1)
#define rc ((p << 1) | 1)
#define mid ((l + r) >> 1) int n, m, k, d, ans, zero; struct Tree {
int sum, la, ra, ma, li, ri, mi;
} t[N << ]; void pushup(int p) {
t[p].sum = t[lc].sum + t[rc].sum;
t[p].la = max(t[lc].la, t[lc].sum + t[rc].la);
t[p].ra = max(t[rc].ra, t[rc].sum + t[lc].ra);
t[p].ma = max(t[lc].ra + t[rc].la, max(t[lc].ma, t[rc].ma));
t[p].li = min(t[lc].li, t[lc].sum + t[rc].li);
t[p].ri = min(t[rc].ri, t[rc].sum + t[lc].ri);
t[p].mi = min(t[lc].ri + t[rc].li, min(t[lc].mi, t[rc].mi));
} void build(int p, int l, int r) {
if (l == r) {
scanf("%d", &t[p].sum);
t[p].la = t[p].ra = t[p].ma = t[p].sum;
t[p].li = t[p].ri = t[p].mi = t[p].sum;
if (!t[p].sum) zero++;
return;
}
build(lc, l, mid);
build(rc, mid + , r);
pushup(p);
} void update(int p, int l, int r, int x, int q) {
if (l > x || r < x) return;
if (l == r) {
if (!t[p].sum && q) zero--;
if (t[p].sum && !q) zero++;
t[p].sum = q;
t[p].la = t[p].ra = t[p].ma = t[p].sum;
t[p].li = t[p].ri = t[p].mi = t[p].sum;
return;
}
update(lc, l, mid, x, q);
update(rc, mid + , r, x, q);
pushup(p);
} int main() {
scanf("%d", &n);
build(, , n);
scanf("%d", &m);
for (int i = ; i <= m; i++) {
scanf("%d%d", &k, &d);
update(, , n, k, d);
if (t[].ma == t[].sum && !zero) ans = t[].sum - t[].mi;
else if (t[].mi == t[].sum && !zero) ans = t[].ma;
else ans = max(t[].ma, t[].sum - t[].mi);
printf("%d\n", ans);
} return ;
}

T4 [JZOJ3512] show

题目描述

  有三支队伍,分别是A,B,C。有n个游戏节目,玩第i个游戏,队伍A可以得到的分数是A[i],队伍B可以得到的分数是B[i],队伍C可以得到的分数是C[i]。由于时间有限,可能不是每个节目都能玩,于是节目主持人决定要从n个游戏节目里面挑选至少k个节目出来(被选中的节目不分次序),使得队伍A成为赢家。队伍A能成为赢家的条件是队伍A的总得分要比队伍B的总得分要高,同时也要比队伍C的总得分要高。节目主持人有多少种不同的选取方案?

数据范围

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

  对于 $100\%$ 的数据,$2 \leq N \leq 34$,$1 \leq K \leq min(N,7)$,$1 \leq A,B,C \leq 10^9$

分析

  防AK题,当然是选择秒打暴力啊

  仔细观察,会发现这题的数据范围很诡异,状压显然是不行的,又好像没什么方法可以剪枝

  但是,题目中给了一个很小的 $k$,我们会想到用总合法方案数减去不满足 $k$ 限制的合法方案数得到答案

  在不满足 $k$ 的限制范围中,枚举的方案数量最多是 $\sum\limits_{i=0}^6 \binom{34}{i}$,即 $1676116$ 种,这是不会超时的

  然后在求总合法方案数时,直接搜索时肯定过不了的,我们可以把前一半节目和后一半节目分为两部分

  对于每个部分,枚举的方案数最多为 $2^{17}$,我们可以求出两个部分中每种方案得到的一对值 $(ab_1,ac_1)$,$(ab_2,ac_2)$,其中 $ab$ 为 $A$ 组总得分减去 $B$ 组总得分,$ac$ 为 $A$ 组总得分减去 $C$ 组总得分

  显然,一种完整方案要成立,必须同时满足 $ab_1+ab_2>0$ 和 $ac_1+ac_2>0$

  所以我们可以枚举第一部分中的所有方案,在第二部分中找出与之匹配能够成立的方案

  当然这样就需要用树状数组/线段树之类的数据结构来保存第二部分中的所有方案,同时还需要离散化/动态开点

  时间复杂度为 $O(2^{17} \, log \; 2^{17}+1676116) \doteq O(1807193)$

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 40
#define M (1 << 17) + 5 int n, k, t1, t2, t, tr[M << ];
ll ansk, ans, a[N], b[N], c[N]; struct Data {ll ab, ac;} d1[M], d2[M];
struct Node {ll x, y; int mark;} d[M << ]; bool cmp1(Data x, Data y) {return x.ac < y.ac;}
bool cmp2(Data x, Data y) {return x.ac > y.ac;}
bool cmp(Node x, Node y) {return x.x < y.x;}; void dfsk(int x, int sum, ll sa, ll sb, ll sc) {
if (sum == k) return;
if (sa > sb && sa > sc) ansk++;
for (int i = x + ; i <= n; i++)
dfsk(i, sum + , sa + a[i], sb + b[i], sc + c[i]);
} void dfs1(int x, ll sa, ll sb, ll sc) {
d1[++t1].ab = sa - sb, d1[t1].ac = sa - sc;
for (int i = x + ; i <= (n >> ); i++)
dfs1(i, sa + a[i], sb + b[i], sc + c[i]);
} void dfs2(int x, ll sa, ll sb, ll sc) {
d2[++t2].ab = sa - sb, d2[t2].ac = sa - sc;
for (int i = x + ; i <= n; i++)
dfs2(i, sa + a[i], sb + b[i], sc + c[i]);
} int lowbit(int x) {return x & -x;} void update(int x) {
while (x <= t) tr[x]++, x += lowbit(x);
} int query(int x) {
int sum = ;
while (x) sum += tr[x], x -= lowbit(x);
return sum;
} int main() {
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++) scanf("%lld", a + i);
for (int i = ; i <= n; i++) scanf("%lld", b + i);
for (int i = ; i <= n; i++) scanf("%lld", c + i);
dfsk(, , , , ); dfs1(, , , ); dfs2(n >> , , , );
for (int i = ; i <= t1; i++)
d[i].x = d1[i].ab, d[i].y = i, d[i].mark = ;
for (int i = ; i <= t2; i++)
d[t1 + i].x = -d2[i].ab, d[t1 + i].y = i, d[t1 + i].mark = ;
sort(d + , d + t1 + t2 + , cmp);
d[].x = -;
for (int i = ; i <= t1 + t2; i++) {
if (d[i].x != d[i - ].x) t++;
if (!d[i].mark) d1[d[i].y].ab = t;
else d2[d[i].y].ab = t;
}
sort(d1 + , d1 + t1 + , cmp1);
sort(d2 + , d2 + t2 + , cmp2);
for (int i = , j = ; i <= t1; i++) {
while (j <= t2 && d1[i].ac + d2[j].ac > )
update(d2[j].ab), j++;
ans += query(d1[i].ab - );
}
printf("%lld\n", ans - ansk); return ;
}

2019-08-13 纪中NOIP模拟B组的更多相关文章

  1. 2019-08-21 纪中NOIP模拟A组

    T1 [JZOJ6315] 数字 题目描述

  2. 2019-08-20 纪中NOIP模拟A组

    T1 [JZOJ6310] Global warming 题目描述 给定整数 n 和 x,以及一个大小为 n 的序列 a. 你可以选择一个区间 [l,r],然后令 a[i]+=d(l<=i< ...

  3. 2019-08-18 纪中NOIP模拟A组

    T1 [JZOJ6309] 完全背包 题目描述

  4. 2019-08-15 纪中NOIP模拟B组

    T1 [JZOJ3455] 库特的向量 题目描述 从前在一个美好的校园里,有一只(棵)可爱的弯枝理树.她内敛而羞涩,一副弱气的样子让人一看就想好好疼爱她.仅仅在她身边,就有许多女孩子想和她BH,比如铃 ...

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

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

  6. 2019-08-25 纪中NOIP模拟A组

    T1 [JZOJ6314] Balancing Inversions 题目描述 Bessie 和 Elsie 在一个长为 2N 的布尔数组 A 上玩游戏. Bessie 的分数为 A 的前一半的逆序对 ...

  7. 2019-08-23 纪中NOIP模拟A组

    T1 [JZOJ2908] 矩阵乘法 题目描述 给你一个 N*N 的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第 K 小数. 数据范围 对于 $20\%$ 的数据,$N \leq 100$,$Q ...

  8. 2019-08-20 纪中NOIP模拟B组

    T1 [JZOJ3490] 旅游(travel) 题目描述 ztxz16如愿成为码农之后,整天的生活除了写程序还是写程序,十分苦逼.终于有一天,他意识到自己的生活太过平淡,于是决定外出旅游丰富阅历. ...

  9. 2019-08-09 纪中NOIP模拟B组

    T1 [JZOJ1035] 粉刷匠 题目描述 windy有N条木板需要被粉刷. 每条木板被分为M个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一 ...

  10. 2019-08-17 纪中NOIP模拟B组

    T1 [JZOJ3503] 粉刷 题目描述 鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个N*M的矩阵,有一些格子是有污点的.现在鸡腿可以竖着刷一次,覆盖连续的最多C列,或者横着刷一次, ...

随机推荐

  1. 在Idea中jdk11和jdk8环境变量的切换

    先配置好jdk11和jdk8环境变量 idea(2019.3)中jdk版本切换(jdk8和jdk11) 快捷键ctrl + shift + alt +s ,将jdk11修改为jdk1.8 完成后,显示 ...

  2. Bounce 弹飞绵羊 HYSBZ - 2002 分块

    //预处理出以这个点为起点并跳出这个块的次数和位置 //更新一个点的弹力系数可以只更新这个点以及这个块内之前的点 #include<stdio.h> #include<algorit ...

  3. 有关css编写文字动态下划线

    <div class="main_text">哈哈这就是我的小视频</div> 上面为html代码 接下来进行css的编写 .main_text{ posi ...

  4. 如何安装selenium框架

    半年前因不满自己工作内容,便到处寻求资料,偶遇分享一套全套教程.开始学习python,后接触selenium有关内容. 前期因为配置环境花了些许时间,后来解决了,回想是如此简单 安装步骤 1.下载py ...

  5. 【Android】java中调用JS的方法

    最近因为学校换了新的教务系统,想做一个模拟登陆功能,发现登陆的账号和密码有一个js脚本来进行加密 整理了一下java中执行JS的方法 智强教务 账号 密码 加密方法 var keyStr = &quo ...

  6. 用R实现范式编程

    面向函数范式编程(Functional programming) 模拟简单的随机过程 模拟一个简单的随机过程:从N~(0,1)标准正态分布中产生100个随机值,反复5次得到一个list,再以每个lis ...

  7. 42.Pycharm连接数据库出现错误:1045、1044:django.db.utils.OperationalError: (1045, "Access denied for user 'Whois'@'localhost' (using password: YES)”)

    1.在pycharm中设置好数据库的连接信息,连接数据库db01, DATABASES = { 'default': { # 指定所使用的的数据库引擎 'ENGINE': 'django.db.bac ...

  8. JavaSE学习笔记(3)---面向对象三大特性

    JavaSE学习笔记(3)---面向对象三大特性 面向对象的三大特征:继承.封装.多态 1.封装 面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改.然 ...

  9. Codeforces Round #592 (Div. 2) E

    给你一个数组,你最多可以进行k次操作,每次操作可以使一个数+1或者-1,问操作之后数组的极差最小可能是多少 利用map来模拟移动,可以观察到每次应该选择数量少的一组数让他们进行移动是最优的 int m ...

  10. 阿里云IIS服务器SSL证书安装

    一.前提条件 申请证书时需要选择 系统自动创建CSR. 申请证书时如果选择手动创建CSR,则不会生成证书文件.您需要选择其他服务器下载.crt证书文件后,使用openssl命令将.crt文件的证书转换 ...