Prob. 1

Desc. & Link.

暴力为 \(\Theta(NK)\)。

正解(也许):

把每一个全为正整数的子段找出来。

然后判断一下中间连接的情况即可。

但是这样决策情况太多了。

我们需要考虑贪心。

把所有整数段的个数记为 \(totP\),每个子段的区间记为 \([posL_{i},posR_{i}]\),区间和记为 \(sumP_{i}\)

把其他的负数段个数记为 \(totN\),区间和记为 \(sumN_{i}\)。

当 \(totP\le k\) 答案显然。

我们需要考虑的是 \(totP>k\) 的情况。

我们把整数段、负数段缩成点。

然后问题还是最多选 \(k\) 段的最大子段和。

不过我们的序列有个性质:相邻数的正负性不同。(gu)

好了放弃以上想法。

模拟 \(k\) 轮找全局最大子段和,找到一次把子段乘上 \(-1\)。

#include <cstdio>

typedef long long LL;

const int MAXN = 1e5 + 5;

int rint () {
int x = 0, f = 1; char c = getchar ();
for ( ; c < '0' || c > '9'; c = getchar () ) f = c == '-' ? -1 : f;
for ( ; c >= '0' && c <= '9'; c = getchar () ) x = ( x << 3 ) + ( x << 1 ) + ( c & 15 );
return x * f;
} template<typename _T>
void wint ( _T x ) {
if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
if ( x > 9 ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} template<typename _T> _T MAX ( const _T x, const _T y ) { return x < y ? y : x; }
template<typename _T> void swapp ( _T &x, _T &y ) { _T w = x; x = y; y = w; } struct nodeS {
LL val, dat, p, s;
int l, r, pl, pr, sl, sr;
nodeS ( LL V = 0, LL D = 0, LL P = 0, LL S = 0,
int L = 0, int R = 0, int Pl = 0, int Pr = 0, int Sl = 0, int Sr = 0 ) {
val = V, dat = D, p = P, s = S, l = L, r = R, pl = Pl, pr = Pr, sl = Sl, sr = Sr; }
} nodes[MAXN * 4][2]; int n, k, a[MAXN];
bool tag[MAXN * 4]; nodeS Merge ( const nodeS lch, const nodeS rch ) {
nodeS ret;
ret.val = lch.val + rch.val;
ret.p = MAX ( lch.p, lch.val + rch.p );
if ( ret.p == lch.p ) ret.pl = lch.pl, ret.pr = lch.pr;
else ret.pl = lch.pl, ret.pr = rch.pr;
ret.s = MAX ( rch.s, rch.val + lch.s );
if ( ret.s == rch.s ) ret.sl = rch.sl, ret.sr = rch.sr;
else ret.sl = lch.sl, ret.sr = rch.sr;
ret.dat = MAX ( lch.s + rch.p, MAX ( lch.dat, rch.dat ) );
if ( ret.dat == lch.dat ) ret.l = lch.l, ret.r = lch.r;
else if ( ret.dat == rch.dat ) ret.l = rch.l, ret.r = rch.r;
else ret.l = lch.sl, ret.r = rch.pr;
return ret;
} void Upt ( const int x ) {
nodes[x][0] = Merge ( nodes[x << 1][0], nodes[x << 1 | 1][0] );
nodes[x][1] = Merge ( nodes[x << 1][1], nodes[x << 1 | 1][1] );
} void Spr ( const int x ) {
if ( ! tag[x] ) return;
swapp ( nodes[x << 1][0], nodes[x << 1][1] );
swapp ( nodes[x << 1 | 1][0], nodes[x << 1 | 1][1] );
tag[x << 1] ^= 1, tag[x << 1 | 1] ^= 1, tag[x] = 0;
} void Build ( const int x, const int l, const int r ) {
if ( l == r ) {
nodes[x][0] = nodeS ( a[l], a[l], a[l], a[l], l, l, l, l, l, l );
nodes[x][1] = nodeS ( -a[l], -a[l], -a[l], -a[l], l, l, l, l, l, l );
return;
}
int mid = ( l + r ) >> 1;
Build ( x << 1, l, mid );
Build ( x << 1 | 1, mid + 1, r );
Upt ( x );
} void Modify ( const int x, const int l, const int r, const int segL, const int segR ) {
if ( l > segR || r < segL ) return;
if ( l >= segL && r <= segR ) {
swapp ( nodes[x][0], nodes[x][1] );
tag[x] ^= 1;
return;
}
int mid = ( l + r ) >> 1;
Spr ( x );
Modify ( x << 1, l, mid, segL, segR );
Modify ( x << 1 | 1, mid + 1, r, segL, segR );
Upt ( x );
} int main () {
n = rint (), k = rint ();
for ( int i = 1; i <= n; ++ i ) a[i] = rint ();
Build ( 1, 1, n );
LL ans = 0;
while ( k -- > 0 ) {
nodeS ret = nodes[1][0];
if ( ret.dat < 0 ) break;
Modify ( 1, 1, n, ret.l, ret.r );
ans += ret.dat;
}
wint ( ans ), putchar ( '\n' );
return 0;
}

Prob. 2

Desc. & Link.

设 \(f_{i,0/1}\) 表示把 \(a_{i}\) 往头/尾放可以得到的最多的上升子序列。

\[f_{i,0}=\begin{cases}\max\{f_{j,0},f_{j,1}\}+1,a_{i}<a_{j} \\\max\{f_{j,0},f_{j,1}\},a_{i}\ge a_{j}\end{cases} \\f_{i,1}=\begin{cases}\max\{f_{j,0},f_{j,1}\},a_{i}<a_{j} \\\max\{f_{j,0},f_{j,1}\}+1,a_{i}\ge a_{j}\end{cases}
\]

不行。

考虑普通的 LIS 怎么做。

\[f_{i}=\max\{f_{j}\}+1,a_{i}>a_{j}
\]
\[a_{i}<a_{j},i<j
\]

选择往前放的元素,放得越晚越靠前。

选择往后放的元素,放得越晚越靠后。

那么需要做的是把相对较大的元素往后,相对较小的元素往前。

连边,把李三花后的 \(a_{i}\) 连向 \(\text{trans}(i,0),\text{trans}(i,1),\text{trans}(x,0/1)=n-x+1/x+n\)。

#include <cstdio>
#include <algorithm> using namespace std; const int MAXN = 2e5 + 5; int rint () {
int x = 0, f = 1; char c = getchar ();
for ( ; c < '0' || c > '9'; c = getchar () ) f = c == '-' ? -1 : f;
for ( ; c >= '0' && c <= '9'; c = getchar () ) x = ( x << 3 ) + ( x << 1 ) + ( c & 15 );
return x * f;
} template<typename _T>
void wint ( _T x ) {
if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
if ( x > 9 ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} template<typename _T> _T MAX ( const _T x, const _T y ) { return x < y ? y : x; } struct Value {
int val, pos;
Value ( int V = 0, int P = 0 ) { val = V, pos = P; }
bool operator < ( const Value &another ) { return val < another.val; }
} vals[MAXN]; struct GraphSet {
int to, nx;
GraphSet ( int T = 0, int N = 0 ) { to = T, nx = N; }
} as[MAXN * 2]; int n, cnt, len, degin[MAXN], a[MAXN], b[MAXN], buc[MAXN], sywf[MAXN]; void makeEdge ( const int u, const int v ) { as[++ cnt] = GraphSet ( v, degin[u] ), degin[u] = cnt; }
int Trans ( const int x, const int y ) { return ! y ? n - x + 1 : x + n; } void ADD ( int p, const int x ) { for ( ; p <= ( n << 1 ); p += p & -p ) sywf[p] = MAX ( sywf[p], x ); }
int ASK ( int p ) { int res = 0; for ( ; p; p -= p & -p ) res = MAX ( res, sywf[p] ); return res; }
int CMP ( const int x, const int y ) { return x > y; } int main () {
// freopen ( "dequexlis.in", "r", stdin );
// freopen ( "dequexlis.out", "w", stdout );
n = rint ();
for ( int i = 1; i <= n; ++ i ) a[i] = b[i] = rint ();
sort ( b + 1, b + 1 + n );
len = unique ( b + 1, b + 1 + n ) - b - 1;
for ( int i = 1; i <= n; ++ i ) a[i] = lower_bound ( b + 1, b + 1 + len, a[i] ) - b;
for ( int i = 1; i <= n; ++ i ) vals[i] = Value ( a[i], i );
for ( int i = 1; i <= n; ++ i ) {
makeEdge ( a[i], Trans ( i, 0 ) );
makeEdge ( a[i], Trans ( i, 1 ) );
}
int BUC = 0;
for ( int x_x = 1; x_x <= n; ++ x_x ) {
int u = x_x;
BUC = 0;
for ( int i = degin[u]; i; i = as[i].nx ) {
int v = as[i].to;
buc[++ BUC] = v;
}
sort ( buc + 1, buc + 1 + BUC, CMP );
for ( int i = 1; i <= BUC; ++ i ) ADD ( buc[i], 1 + ASK ( buc[i] - 1 ) );
}
wint ( ASK ( n << 1 ) ), putchar ( '\n' );
return 0;
} /* Jesus bless all */

Prob. 3

放弃人生打了个 50 的记搜。

#include <cstdio>
#include <map>
#define mod ( 998244853 ) using namespace std; template<typename _T> _T MAX ( const _T x, const _T y ) { return x < y ? y : x; } int n, m; namespace Course {
const int MAXN = 255;
int f[MAXN][MAXN][MAXN];
bool vis[MAXN][MAXN][MAXN]; int dfs ( const int mx, const int a, const int b ) {
if ( vis[a][b][mx] ) return f[a][b][mx];
vis[a][b][mx] = 1;
if ( a == n && b == m ) return f[a][b][mx] = mx;
if ( a < n ) f[a][b][mx] = ( f[a][b][mx] + dfs ( MAX ( mx, a - b + 1 ), a + 1, b ) ) % mod;
if ( b < m ) f[a][b][mx] = ( f[a][b][mx] + dfs ( mx, a, b + 1 ) ) % mod;
return f[a][b][mx];
}
} int main () {
// freopen ( "maxpsum.in", "r", stdin );
// freopen ( "maxpsum.out", "w", stdout );
scanf ( "%d%d", &n, &m );
if ( n <= 250 && m <= 250 ) printf ( "%d\n", Course :: dfs ( 0, 0, 0 ) );
// else printf ( "%d\n", Might :: dfs ( 0, 0, 0 ) );
return 0;
}

Prob. 4

Desc. & Link.

Record - Nov. 28st, 2020 - Exam. REC的更多相关文章

  1. 18.自动运维工具ansible

    1 Ansible 介绍和架构 1.1 Ansible介绍 ansible 的名称来自科幻小说<安德的游戏>中跨越时空的即时通信工具,使用它可以在相距数光年的 距离,远程实时控制前线的舰队 ...

  2. 视频直播点播nginx-rtmp开发手册中文版

    2016年8月18日12:42:35 参照官方文档https://github.com/arut/nginx-rtmp-module/wiki/Directives 请注意这个是粗翻译版,仅供参考,不 ...

  3. C++文件输入和输出

    1.引入头文件fstreamfstream头文件定义了用于文件输入的类ifstream和文件输出的类ofstream 2.写文件1)创建一个ofstream对象来管理输出流2)将该对象与文件关联起来3 ...

  4. 锁大全与 GDB调试

    1.innodb_lock_monitor:打开锁信息的方式 mysql> create table innodb_lock_monitor(id int) engine=InnoDB; Que ...

  5. 浅谈Manacher算法与扩展KMP之间的联系

    首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一   ...

  6. 数据库SQLite在Qt5+VS2012使用规则总结---中文乱码

    VS2012默认格式为 "GB2312-80",而有时我们用到字符串需要显示中文时,就会出现乱码.下面仅就Qt5和VS2012中使用数据库SQLite时,做一个简单的备忘录 #in ...

  7. rtmp指令解释--转

    指令 Core rtmp 语法:rtmp { ... } 上下文:根 描述:保存所有 RTMP 配置的块. server 语法:server { ... } 上下文:rtmp 描述:声明一个 RTMP ...

  8. Oracle中特殊的变量类型

    1.%TYPE 允许用户动态地将数据库中某一列的数据类型与PL/SQL中某个变量关联.语法如下: variable_name table.column%TYPE   2.%ROWTYPE 允许用户定义 ...

  9. Gluon Datasets and DataLoader

    mxnet.recordio MXRecordIO Reads/writes RecordIO data format, supporting sequential read and write. r ...

  10. 【做题】cf603E——线段树分治

    首先感谢题解小哥,他在标算外又总结了三种做法. 此处仅提及最后一种做法. 首先考虑题目中要求的所有结点度数为奇数的限制. 对于每一个联通块,因为所有结点总度数是偶数,所以总结点数也必须是偶数的.即所有 ...

随机推荐

  1. 使用 ChatGPT 的 7 个技巧 | Prompt Engineering 学习笔记

    概述 前段时间在 DeepLearning 学了一门大火的 Prompt 的课程,吴恩达本人授课,讲的通俗易懂,感觉受益匪浅,因此在这里总结分享一下我的学习笔记. 为什么要学习 Prompt ? 因为 ...

  2. Bioconductor 中的 R 包安装教程

    Bioconductor 是一个基于 R 语言的生物信息软件包,主要用于生物数据的注释.分析.统计.以及可视化(http://www.bioconductor.org). 总所周知,Bioconduc ...

  3. Spring Boot实现高质量的CRUD-1

    1.前言 ​ 在Spring Boot的SMM框架(SpringBoot+Mysql+Mybatis)的WEB项目中,CRUD(增删改查)大致占了50%-70%左右的工作量.提高CRUD的代码质量,提 ...

  4. https 原理分析进阶-模拟https通信过程

    大家好,我是蓝胖子,之前出过一篇https的原理分析 ,完整的介绍了https概念以及通信过程,今天我们就来比较完整的模拟实现https通信的过程,通过这篇文章,你能了解到https核心的概念以及原理 ...

  5. 深度解读AIGC存储解决方案

    5月26日,2023数据基础设施技术峰会在苏州举办,腾讯云首席存储技术专家温涛受邀出席并分享了腾讯云领先的存储技术在AIGC场景中的应用,通过对AIGC业务流程和场景的提炼,从内容生成.内容审核和内容 ...

  6. C++ 惯用法之 Copy-Swap 拷贝交换

    C++ 惯用法之 Copy-Swap 拷贝交换 这是"C++ 惯用法"合集的第 3 篇,前面 2 篇分别介绍了 RAII 和 PIMPL 两种惯用法: RAII: Resouce ...

  7. java解析CSV文件(zipFiles 打成压缩包 exportObeEventDataExcel 前端页面响应)

    JAR包及代码17:39:09 <!-- https://mvnrepository.com/artifact/com.opencsv/opencsv --> <dependency ...

  8. 10/29/2017_C语言_三道题

    1. 用标准C编程:找出整形数字1-100之间的素数,并打印出来.(素数:除了1和自己本身可以被整除.) 2. 用标准C编程:有两个整形变量m.n,求出这两个数的最小公倍数. 3. 用标准C编程:输出 ...

  9. 【转载】Linux虚拟化KVM-Qemu分析(十一)之virtqueue

    转载自: 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者 ...

  10. Linux 命令:time

    参考链接: time 命令