我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5443

这题能在暴力美学分组中占压轴地位,是不简单的。我从未见过如此灵性的暴力题目(也许是我太弱了题目写少了)。

我们令\(ans[j][i]\)表示与串\([i,i+l-1]\)距离为\(j\)的串的个数,最暴力的方法显然是直接\(O(n^2*l)\)去匹配的。

但是其中我们会对一些字符进行若干次重复的比较。比如\([1,3]\)和\([2,4]\)匹配时以及\([2,4]\)和\([3,5]\)都会判断\(a[3]\)是否等于\(a[3]\)。很显然这种冗余的操作是不优的。那么我们怎么减少这样的操作呢?

性质:如果我们已经知道了\([l1,r1]\)与\([l2,r2]\)的距离,那么我们可以在\(O(1)\)时间内算出\([l1+1,r1+1]\)与\([l2+1,r2+1]\)的距离。设前者为\(s\),后者为\(t\),那么\(t=s-(a[l1]!=a[l2])+(a[r1+1]!=a[r2+1])\)。

也就是说,我们可以在\(O(n)\)的时间内匹配完\(n\)条子串。

我们枚举一个\(len\),令\(h1\)为\(1\),\(h2\)为\(h1+len\),然后暴力匹配\([h1,h1+l-1]\)和\([h2,h2+l-1]\),再在\(O(n)\)的时间内把所以起点下标差为\(len\)的所以串对匹配完并且统计答案。

枚举\(len\)的复杂度乘以匹配的复杂度为\(O(n^2)\),我们成功消去了一个\(l\)!

但是这题还卡空间……所以\(ans\)数组开不了那么大。

可是出题人关上了一扇门,却为我们留了一扇窗。

\(query\)的次数很小。我们可以将\([1,l]\)之内的所有数字都找到离自己最近的大于等于自己的\(k\),用一个\(pos[i]\)记录这个\(k\)。然后每次匹配出来距离为\(dis\),我们就把答案累计到\(ans[pos[dis]][i]\)里去,最后前缀和一下,就可以求出所有的\(query\)了。

时间复杂度:\(O(n^2)\)

空间复杂度:\(O(nq)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std; const int maxn=1e4+5; bool v[maxn];
int n,m,l,cnt;
int ans[101][maxn];
int a[maxn],k[101],pos[maxn]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} void solve() {
for(int len=1;len<=n-l;len++) {//枚举len
int res=0,h1=1,h2=h1+len;//res记录当前两个串的距离,h1是第一个串的起点,h2是第二个串的起点
for(int i=0;i<l;i++)
if(a[h1+i]!=a[h2+i])res++;
ans[pos[res]][h1]++;
ans[pos[res]][h2]++;//答案累计到ans[pos[res]][h1]和ans[pos[res]][h2]里
while(1) {
if(h2+l>n)break;//如果h2往后没有l那么长了就break
res-=(a[h1]!=a[h2]);
res+=(a[h1+l]!=a[h2+l]);//O(1)转移
h1++;h2++;
ans[pos[res]][h1]++;
ans[pos[res]][h2]++;//累计答案
}
}
} int main() {
n=read();l=read();
for(int i=1;i<=n;i++)
a[i]=read();
m=read();pos[1]=1;//pos[1]等于1
for(int i=1;i<=m;i++)
k[i]=read(),v[k[i]]=1;//我这里用差分的方法求每个数的pos
for(int i=2;i<=l;i++)
pos[i]=pos[i-1]+v[i-1];//如果是在(k[i],k[i+1]]之间的数,pos[i]就是i+1
solve();
for(int i=1;i<=n-l+1;i++)
for(int j=1;j<=m;j++)
ans[j][i]+=ans[j-1][i];//前缀和统计答案
for(int i=1;i<=m;i++) {
for(int j=1;j<=n-l+1;j++)
printf("%d ",ans[pos[k[i]]][j]);//离线输出答案
puts("");
}
return 0;
}

BZOJ5443:[CEOI2018]Lottery的更多相关文章

  1. xcode6中如何添加pch文件

    在Xcode6之前,新建一个工程的时候,系统会帮我们自动新建一个以工程名为名字的pch (precompile header)文件,在开发过程中,可以将那些整个工程都广泛使用的头文件包含在该文件下,编 ...

  2. dotNet core 应用部署至 centos(超详解附截图)

    文章来源:公众号-智能化IT系统. 需要安装的插件以及支撑架构 1.dotnetSDK dotnet 相关命令是属于 .NET Core command-line (CLI) 的一部分,Microso ...

  3. 7.Mysql存储引擎

    7.表类型(存储引擎)的选择7.1 Mysql存储引擎概述 mysql支持插件式存储引擎,即存储引擎以插件形式存在于mysql库中. mysql支持的存储引擎包括:MyISAM.InnoDB.BDB. ...

  4. 开放通用Api,总有你喜欢的

    接口文档 目录 通用 更新记录 接口列表 一.福彩-双色球接口 指定期号中奖号码 最新中奖号码信息 获取双色球中奖信息列表 二.节假日及万年历 指定日期的节假日及万年历信息 指定多个日期的节假日及万年 ...

  5. .netcore部署centos

    前言:最近公司有个项目用 .netcore开发的项目,然后闲的没事就研究如果发布到Linux系统上 需要安装的插件以及支撑架构 1.dotnetSDK 2.jexus Jexus 是Linux平台上 ...

  6. 初次接触python时,整理的一些基础操作

    1.window下python简单使用 (1).使用工具网址 https://jingyan.baidu.com/article/9f7e7ec0ec2e676f2915545f.html (2).各 ...

  7. 如何用 Python 写一个简易的抽奖程序

    不知道有多少人是被这个头图骗进来的:) 事情的起因是这样的,上周有同学问小编,看着小编的示例代码敲代码,感觉自己也会写了,如果不看的话,七七八八可能也写的出来,但是一旦自己独立写一段程序,感觉到无从下 ...

  8. 利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客挖掘机 PS:如有需要Python学习资料的小伙伴可以加点击下 ...

  9. java web 开发三剑客 -------电子书

    Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知In ...

随机推荐

  1. 白昼夢 / Daydream(模拟)

    C - 白昼夢 / Daydream Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement You ...

  2. Apache Maven pom文件

    Welcome to Apache Maven Apache Maven is a software project management and comprehension tool. Based ...

  3. 【logback】认识logback

    一. Reference:http://www.cnblogs.com/yongze103/archive/2012/05/05/2484753.html 1. Logback为取代log4j而生,l ...

  4. linux 如何查找命令的路径

    linux 下,我们常使用 cd ,grep,vi 等命令,有时候我们要查到这些命令所在的位置,如何做呢? linux下有2个命令可完成该功能:which ,whereis which 用来查看当 前 ...

  5. LeetCode:区域和检索【303】

    LeetCode:区域和检索[303] 题目描述 给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点. 示例: 给定 nums = [ ...

  6. mysql管理工具之pt-heartbeat

    之前我一直用Seconds_behind_master来衡量主从的延迟,今天看到文档,才觉得多么不可靠!以下是官方文档的描述: In essence, this field measures the ...

  7. 20165101刘天野 2018-2019-2《网络对抗技术》Exp6 信息搜集与漏洞扫描

    目录 20165101刘天野 2018-2019-2<网络对抗技术>Exp6 信息搜集与漏洞扫描 1.实验内容 1.1 各种搜索技巧的应用 1.2 DNS IP注册信息的查询 1.3 基本 ...

  8. Map集合按照value和key进行排序

    最近由于特殊的业务需求,需要做相关数据排序,下面就贴出其中的将map集合中按照value或者key进行排序的代码,后面再具体详说. /** * map 集合排序 * @param map * @ret ...

  9. String类型的对象,是保存在堆里还是在栈里呢?

    在Java的实现中,new出来的String对象一般是放在堆中的. 如果是 String s ="xxx"; 这种,那就是放在常量池中. JDK6将常量池放在方法区中. 方法区此时 ...

  10. [算法]数组的partition调整

    题目一: 给定一个有序数组arr,调整arr使得这个数组的左半部分没有重复部分且升序,而不用保证右部分是否有序. 例如:arr=[1,2,2,2,3,3,4,5,6,6,7,7,8,8,9,9],调整 ...