我对状态空间的理解: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. AOP原理及其实现

       AOP 是 Aspect-Oriented programming 的缩写,中文翻译为面向切面编程,它是OOP(Object-Oriented Programing,面向对象编程)的补充和完善. ...

  2. [IOS]从零开始搭建基于Xcode7的IOS开发环境和免开发者帐号真机调试运行第一个IOS程序HelloWorld

    首先这篇文章比较长,若想了解Xcode7的免开发者帐号真机调试运行IOS程序的话,直接转到第五部分. 转载请注明原文地址:http://www.cnblogs.com/litou/p/4843772. ...

  3. python字典中包含列表时:查找字典中某个元素及赋值

    直接上代码: 运行效果:

  4. 【python】-- 深浅copy、集合

    深浅copy 1.数字.字符串的copy: 赋值(=).浅拷贝(copy)和深拷贝(deepcopy)其实都一样,因为它们永远指向同一个内存地址: >>> import copy & ...

  5. 2017-2018-1 20179209《Linux内核原理与分析》第八周作业

    Linux内核如何装载和启动一个可执行程 一.实验 1.1理解编译链接的过程和ELF可执行文件格式. 1.1.1编译链接过程 能用图说明的问题,就少用文字描述: 1.1.2ELF可执行文件 ELF可执 ...

  6. Django 之 ORM 字段和字段参数

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  7. 改善程序与设计的55个具体做法 day5

    条款12:复制对象时勿忘其每一个成分 这里的复制是拷贝构造和operator= 每一个成分有几个维度: 1.每个成员变量 这个很好理解,添加新的成员时也要记得为每个新添加的成员执行合适的复制操作 2. ...

  8. GIT笔记:将项目发布到GITHUB

    GIT笔记:将项目发布到GITHUB 本机配置 1.在项目目录初始化GIT $ git init 2.用命令git add告诉Git,把文件添加到仓库 $ git add . // 这里是所有文件,用 ...

  9. static_new

    <?php //在::操作符的左边写上类的名称来静态地访问某个成员,这样就可以避免创建类的实例. //这样不仅可以省略掉实例化类的代码,而且还会更高效,因为类的每个实例都会占用一小部分的系统资源 ...

  10. 每天一个Linux命令(22)find命令_命令详解

        find命令的一些常用参数的常用实例和用时的注意事项.     实例:     (1)-name参数: 1)[sunjimeng@localhost home]$ find ~ -name & ...