【BZOJ 3636】教义问答手册 (分治+整体二分+dp)

description

“汉中沃野如关中,四五百里烟蒙蒙。黄云连天夏麦熟,水稻漠漠吹秋风。”——摘自 黄裳《汉中行》
“泉岭精神不朽,汉中诸球永生。”——摘自《泉岭精神创立者语录》
“把神犇烤一烤,味道会更好。”——摘自《xhr语录》
“秀恩爱有利于身心健康!”——摘自《泉岭精神集大成者语录》
“楼上说的对!”——摘自《泉岭精神信徒语录合集》
“不会做积分,怎么找妹子!”——摘自《xhr语录》
“切实保护耕地以放置更多的哨戒炮。”——摘自《泉岭精神信徒语录合集》
“就算两个包子一起吃掉,也不能阻止我修筑梯田。”——摘自《泉岭精神创立者语录》
“我来自泉岭,他来自汉中,我们半道而逢。”——摘自《泉岭精神集大成者语录》
【问题描述】
作为泉岭精神的缔造者、信奉者、捍卫者、传承者,Pear决定印制一些教义问答手册,以满足泉岭精神日益增多的信徒。Pear收集了一些有关的诗选、语录,其中部分内容摘录在了【题目背景】里。这些语录是按出现的时间排好序的——Pear很喜欢这样的作风,于是决定在按时间排好序的基础上,选择部分语录,制作成若干本教义问答手册。
一共有N条语录。Pear决定从中选出某一段时间内的所有语录,在此基础上印制大小为L的若干本教义问答手册。Pear对印制的手册有如下要求:
1.每本手册必须包含这个区间内连续的恰好L条语录。
2.不同手册包含的语录不能相同。
3.每条语录有一个“主题相关程度”,这个数可正可负。Pear希望所有手册的语录的“主题相关程度”之和尽可能大。
例如,对于区间[3,15]和L=3,一种选择方法是:[4,6]+[9,11]+[12,14]。这三个区间长度都恰好为L,且互不重叠。
Pear并没有决定选哪段时间的语录,因此他有Q次询问。每次询问,给出两个数[l,r]表示候选语录的范围是第l条到第r条。你能回答出每个询问的最大“主题相关程度”之和么?
Input
第一行两个正整数N,L,含义如上所述。注意对于所有询问,L都是一样的。
第二行N个整数,绝对值<=10000。第i个数表示第i条语录的“主题相关程度”。
接下来Q行,每行两个正整数l和r,表示询问区间。
Output
输出Q行,每行表示这组询问的答案。注意,这个答案可以是0,如果区间负数过于多的话。
Sample Input
15 3
3 1 5 -2 3 -2 -2 2 2 2 0 3 2 -1 0
9
8 10
10 10
9 11
2 14
5 14
5 13
12 13
7 13
2 10

Sample Output
6
0
4
17
11
11
0
11
12
Hint

【数据范围】
对于10%的数据,N=1000,Q=1000,L<=50
对于另外20%的数据,N=100000,Q=100000,L<=5
对于另外20%的数据,N=100000,Q=100000,L<=10
对于100%的数据,N=100000,Q=100000,L<=50
Source
2014年国家集训队十五人互测

solution

从最原始的O(n2)O(n^2)O(n2)暴力入手
f[i][j]f[i][j]f[i][j]表示区间[i,j][i,j][i,j]的答案最大值,sum[i]sum[i]sum[i]表示前缀和
f[i][j]=max(f[i][j−1],f[i][j−L]+sum[j]−sum[j−L])f[i][j]=max(f[i][j-1],f[i][j-L]+sum[j]-sum[j-L])f[i][j]=max(f[i][j1],f[i][jL]+sum[j]sum[jL])
分治,分界线midmidmid[l,r][l,r][l,r]分为左右两个区间

  • 长度为LLL的一段完全属于左区间/右区间
  • 跨越了midmidmid在左右区间都有的一段

第一种完全属于某半边区间的就直接分治递归处理
考虑第二种情况,对每一个l′l'l预处理出在[l′,mid][l',mid][l,mid]区间选了若干个长度为LLL的区间,且在末尾选了xxx个数的最大值,然后对每一个r′r'r预处理出在[mid+1,r‘’][mid+1,r‘’][mid+1,r]区间选了若干个长度为LLL的区间,并在开头选了xxx个数的最大值

fl[i][j]fl[i][j]fl[i][j]:以jjj为左端点,左区间末尾选了iii个数的最大值
fr[i][j]fr[i][j]fr[i][j]:以jjj为右端点,右区间开头选了iii个数的最大值

最后询问可以整体二分一并处理

思路好懂,主要是代码细节很ex人

code

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100005
int n, L, Q;
int p[maxn], ql[maxn], qr[maxn], sum[maxn];//前缀和差分 
int fl[55][maxn], fr[55][maxn];
int Left[maxn], Right[maxn], ans[maxn];
//fl[i][j]:以j为左端点 在末尾选了i个数 的最大值 
//fr[i][j]:以j为右端点 在开头选了i个数 的最大值
//预处理时的最大值只加了完整L的区间值 
void calc_L( int l, int r ) {//对左区间进行预处理 for( int i = 0;i < min( r - l + 1, L );i ++ ) {//枚举跨越mid的在区间末尾选的长度i fl[i][r - i + 1] = 0;for( int j = r - i;j >= l;j -- )//枚举区间的左端点jfl[i][j] = j + L - 1 > r - i ? 0 : max( fl[i][j + 1], fl[i][j + L] + sum[j + L - 1] - sum[j - 1] );//r-i就是不与枚举末尾长度i的起始点相交的第一个点//换言之[r-i+1,r]就是枚举的一个跨越mid的L区间在左半边的部分 //三目运算符判断是否以j为左端点时可以划分出一个完整的在区间的L且不交 (j~j+L-1)}
}
/*
fl[L]:一个跨越mid的长度L区间在左半边就有L个 也就相当于压根没跨越
fr[L]:同理也相当于压根没跨越
此情况恰好与fl[0],fr[0]差了一个L的区间划分循环
故可以由fl[0],fr[0]表示
*/
void calc_R( int l, int r ) {for( int i = 0;i < min( r - l + 1, L );i ++ ) {fr[i][l + i - 1] = 0;//[l,l+i-1]就是枚举的一个跨越mid的L划分区间在右半边的部分 for( int j = l + i;j <= r;j ++ )fr[i][j] = j - L + 1 < l + i ? 0 : max( fr[i][j - 1], fr[i][j - L] + sum[j] - sum[j - L] );//三目运算符判断是否以j为右端点时可以划分出一个完整的在区间的L且不交 (j-L+1~j)} 
}void solve( int Ql, int Qr, int l, int r ) {if( Ql > Qr || r - l + 1 < L ) return;int mid = ( l + r ) >> 1;int lenl = 0, lenr = 0;calc_L( l, mid );calc_R( mid + 1, r );for( int i = Ql;i <= Qr;i ++ ) {int id = p[i];if( qr[id] <= mid ) Left[++ lenl] = id;else if( ql[id] > mid ) Right[++ lenr] = id;else {ans[id] = fl[0][ql[id]] + fr[0][qr[id]];//不存在跨越mid的L区间的情况下 最大值//dp动态规划预处理已经做到局部最优解for( int j = max( 1, L - ( qr[id] - mid ) );j <= mid - ql[id] + 1 && j < L;j ++ )ans[id] = max( ans[id], ( mid - j < l ? 0 : fl[j][ql[id]] ) + ( mid + L - j + 1 > r ? 0 : fr[L - j][qr[id]] ) + sum[mid + L - j] - sum[mid - j] );/*mid-j mid+1+L-j都是两边不相交的第一个点ps:注意括号问题 要把三目运算符整个括在一起 不然会错该跨越mid的区间应为 mid-j+1 ~ mid+1 + L-j - 1  枚举跨越mid的L区间的左区间长度j=max(1,L-(qr[id]-mid))保证至少要有1个 且 该区间的右端点抵到整个询问区间的右端点qr[id]mid-ql[id]+1&&j<L保证至多有L-1个这样右边才至少有一个 且 该区间的最多只能抵到整个询问区间的左端点ql[id]判断一下mid-j<l没有因为只预处理了左端点>=l的其余部分应该全为0同理右边判断一下mid+L-j+1>r没有只处理了右端点<=r其余部分应该全为0然后加上跨越的长度为L的区间的a值和但是好像去掉判断也是AC的???不懂了 按道理不能去掉的啊???ans[id] = max( ans[id], fl[j][ql[id]] + fr[L - j][qr[id]] + sum[mid + L - j] - sum[mid - j + 1 - 1] );*/}}for( int i = 1;i <= lenl;i ++ ) p[Ql + i - 1] = Left[i];for( int i = 1;i <= lenr;i ++ ) p[Ql + lenl + i - 1] = Right[i];solve( Ql, Ql + lenl - 1, l, mid );solve( Ql + lenl, Ql + lenl + lenr - 1, mid + 1, r );//注意这里不再是solve(Ql+lenl,Qr,mid+1,r); 进行分类后有一些询问操作是已经处理了的 
}int main() {scanf( "%d %d", &n, &L );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &sum[i] );sum[i] += sum[i - 1];}scanf( "%d", &Q );for( int i = 1;i <= Q;i ++ ) {p[i] = i;scanf( "%d %d", &ql[i], &qr[i] );}solve( 1, Q, 1, n );for( int i = 1;i <= Q;i ++ )printf( "%d\n", ans[i] );return 0;
} 
//代码参考博客:https://www.cnblogs.com/Orz-IE/p/12039213.html 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YbtOJ-毒瘤染色【LCT】

正题 题目大意 开始时有一张nnn个点没有边的图&#xff0c;qqq次操作加入一条边&#xff0c;如果加入后图是一个沙漠&#xff08;只有边仙人掌的图&#xff09;时才能够加入。 每次加入后询问&#xff1a;开始所有点都是白色&#xff0c;kkk次随机挑一个点染黑&#xff0c;求…

潘淳的苏州.NET俱乐部成立有感!附我的录音

引言&#xff1a;今天是1月21日&#xff0c;我&#xff08;潘淳&#xff09;的生日&#xff0c;两天前刚刚过了他&#xff08;苏俱&#xff09;的生日&#xff0c;微软技术俱乐部&#xff08;苏州&#xff09;在苏州微软正式成立。作为大会活动的策划者和活动发起者之一&#x…

CF1338D:Nested Rubber Bands(树形dp)

解析 神仙题 关键在于找到一个满足题意的充要条件 结论&#xff1a;所有的合法答案一定是由树上一条链及其相邻的点组成的独立集 充分性比较显然&#xff0c;这个东西随便画画就可以构造出合法的解来 所以我们只要考虑必要性 考虑不满足这个结论的方案 可以“发现”它一定是…

cf1512F. Education

cf1512F. Education 题意&#xff1a; 小明想买一个价值为c的东西&#xff0c;他开始打工&#xff0c;他一开始在第i个职务&#xff0c;每天可以挣a[i]&#xff0c;他也可以用一天的时间并且花费b[i]升到i1职务&#xff0c;第i1职务每天可以挣a[i1] 一共有n个职务&#xff0c…

十年 IT 老兵带你通过案例学架构,附C#代码

技术大会上的分享大多高大上&#xff0c;亿级流量、超大型研发团队&#xff0c;虽然值得借鉴&#xff0c;但由于应用场景与研发资源的差异&#xff0c;一般企业并不容易落地。其实&#xff0c;中小型研发团队在IT行业还是占大多数&#xff0c;他们在技术架构方面的问题较多&…

【CF1100F】 Ivan and Burgers (分治+线性基)

description 戳我看题目(づ&#xffe3;3&#xffe3;)づ╭❤&#xff5e; solution 异或和最大 ——关联线性基 线性基&#xff1a; 原序列的每一个数都能由线性基里若干个数异或得到线性基里若干个数的异或结果不可能为0 如果直接线段树合并线性基时间复杂度是无法接受 离…

CF1019D-Large Triangle【计算几何,二分】

正题 题目链接:https://www.luogu.com.cn/problem/CF1019D 题目大意 给出nnn个点&#xff0c;保证没有三点共线&#xff0c;求是否有三个点围成的三角形面积恰好为SSS。 3≤n≤2103,1≤S≤210183\leq n\leq 2\times 10^3,1\leq S\leq 2\times 10^{18}3≤n≤2103,1≤S≤21018 …

11.8模拟:总结

考场 255pts 256070100 比期望低了45分qwq T1莫名其妙挂了五分… 而且似乎把数组开大还能再艹过去一个点 所以格局打开&#xff0c;一定要有梦想&#xff01; 以后即使2^n的暴力也要数组开到1e5 update&#xff1a;考试的时候审题有误&#xff01;“无法放置”的意思是不合法…

浅谈一致性Hash原理及应用

在讲一致性Hash之前我们先来讨论一个问题。问题&#xff1a;现在有亿级用户&#xff0c;每日产生千万级订单&#xff0c;如何将订单进行分片分表&#xff1f;小A&#xff1a;我们可以按照手机号的尾数进行分片&#xff0c;同一个尾数的手机号写入同一片/同一表中。大佬&#xf…

cf1512 G - Short Task

cf1512 G - Short Task 题意&#xff1a; 给一个c&#xff0c;求n&#xff0c;使得n的因数和为c 题解&#xff1a; 求因数和的裸题 我们直接预处理所有数的因数和 筛法求因数和 讲解博客 代码&#xff1a; 埃式筛nloglog&#xff08;1e7&#xff09; 1500ms #include<…

AT2675 [AGC018F] Two Trees (构造+二分图染色+并查集)

description 戳我看题目 solution 正解说是欧拉回路&#xff0c;但是于私而言非常难懂&#xff0c;如果有兴趣可以看香香mm的博客 定义一个点如果有偶数个儿子&#xff0c;就为奇点&#xff1b;如果有奇数个儿子&#xff0c;就为偶点 对于一个点的每个子树自身是满足mod21mo…

YbtOJ-连通的图【结论,线性基】

正题 题目大意 给出nnn个点nk−1nk-1nk−1条边的一张图&#xff0c;求有多少种删除若干条边的方案使得图依旧联通。 1≤n≤105,1≤k≤101\leq n\leq 10^5,1\leq k\leq 101≤n≤105,1≤k≤10 解题思路 注意到kkk很小&#xff0c;我们考虑先搞出一棵dfsdfsdfs树然后剩下的做非树…

模板:容斥优化多重方案背包

所谓容斥优化多重方案背包&#xff0c;就是利用容斥去优化统计方案的多重背包 &#xff08;逃&#xff09; 前言 考场上因为不会这个玩意活活把100分正解挂成了70 qwq 思想还是很妙的 就是先当完全背包做&#xff0c;然后扣去多统计的情况 注意扣去的使用k1个i的方案数是上一…

如何定义开发完成?(Definition of Done)

最近在拜读郑晔的10x程序员工作法&#xff0c;收益良多&#xff0c;文中提出一个概念叫DoD&#xff08;Definition of Done&#xff09;给我的感触颇深。这让我联想到实际工作过程中&#xff0c;经常遇到的扯皮、争吵等各种场景&#xff0c;其实就和这个DoD分不开。一、场景描述…

【正睿2021寒假省选第二轮集训 day 1】串 (后缀自动机+记忆化)

description 定义一个字符串的子串是这个字符串的某个连续区间的字符组成的串。比如&#xff0c;“djq"的子串是"d”,“j”,“q”,“dj”,“jq”,和"djq"。 定义F(a,b)为最长在字符串bb中至少出现一次的字符串a的子串&#xff0c;例如&#xff1a; F(“d…

YbtOJ-序列计数【组合数学,莫队】

正题 题目大意 求有多少个长度在l,rl,rl,r之间&#xff0c;值域是[1,n][1,n][1,n]的严格上升子序列 1≤T,n≤105,1≤l≤r≤1051\leq T,n\leq 10^5,1\leq l\leq r\leq 10^51≤T,n≤105,1≤l≤r≤105 解题思路 先转换成两个前缀和的差&#xff0c;那么相当于我们要快速求 ∑i0m…

欧拉筛法的应用

[数论]-----欧拉筛法的应用 文章目录1.求1~n之间的所有质数2.求1~n之间所有自然数的欧拉函数φ&#xff08;x&#xff09;3.求1~n之间的每个数的因子个数详细推导&#xff1a;代码&#xff1a;4.求1~n之间每个数的因数和详细的推导&#xff1a;代码&#xff1a;筛法求莫比乌斯函…

P5787 二分图 /【模板】线段树分治(线段树分治、并查集)

关于什么是合理的实现 解析 本题把并查集写在了题面上 然而&#xff0c;我却一直沉浸在一个及其通用的判断二分图的方法中&#xff1a; 一个图是二分图的充要条件是它没有奇环 怎么维护这个玩意&#xff1f;带权并查集&#xff01; 怎么套线段树分治&#xff1f;可持久化&…

全新尝试|ComponentOne WinForm和.NET Core 3.0

在微软 Build 2018 开发者大会上&#xff0c;.NET 团队公布了 .NET Core 的下一个主要版本 .NET Core 3.0 的规划蓝图&#xff1a;.NET Core 3将开始支持 Windows 桌面应用程序&#xff0c;包括 Windows Form、Windows Presentation Framework&#xff08;WPF&#xff09;和UWP…

[bzoj3625][Codeforces Round #250]小朋友和二叉树 (生成函数)

description 我们的小朋友很喜欢计算机科学&#xff0c;而且尤其喜欢二叉树。 考虑一个含有n个互异正整数的序列c[1],c[2],…,c[n]。如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{c[1],c[2],…,c[n]}中&#xff0c;我们的小朋友就会将其称作神犇的。并且他认为&am…