今天突然做一道LCT的染色问题的时候突然想到一个两个月前一道没有AC的题目。

链接

大意是,给一个长度为10^4的序列,最多有255个不同的数字,有最多10^5次方个询问,对于每个询问 l,r 输出[l,r]中不同数字的数目。

记得最初的想法是  用f[i][j],存下数字i的第j次出现位置的下标 ,对每次询问,二分查找,判断每个数字i是否存在在[l,r]内的下标。

时间复杂度是最多是 O((10^5)*255*log(10^4)) ,结果比赛的时候超时了,加了读入优化还是不行。

由于比赛的OJ运行偏慢,1s的时限  比赛结束,只有3个人AC,最快的400ms,有一个刚刚好1000ms。

于是我发了个帖子,询问答案,果然得到了更好的思路:

1.

离散化,C[i][j]::A[1]..A[i]中值为j的数的个数
 则数k在[L..R]中出现 <=> C[i][R]-C[i][L-1]>0.
  一次询问时间(255),时间复杂度是O(10^5*255)

已经优化了一点点

代码:

#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <iostream>
using namespace std;
const int INF = ; int f[INF][],pos[INF];
int g[INF];
int n, m, tol;
inline void rd (int &xx) {
char ch = getchar();
while (ch < '' || ch > '') ch = getchar();
for (xx = ; ch >= '' && ch <= ''; ch = getchar() )
xx = xx * + (ch - '');
}
char o[];
inline void putnum (int x) {
if (x == ) {putchar (''); return;}
int i;
for (i = ; x != ; i++, x /= ) o[i] = x % + '' ;
for (i--; i >= ; i--) putchar (o[i]);
putchar ();
}
int main() {
rd (n); rd (m);
for (int i = ; i <= n; i++) {
rd (g[i]);
if (!pos[g[i]]) pos[g[i]] = ++tol;
}
for (int i = ; i <= n; i++) {
for (int j = ; j <= tol; j++)
f[i][j] = f[i - ][j] + (pos[g[i]] == j);
}
for (int i = , l, r; i <= m; i++) {
int ans = ;
rd (l), rd (r);
for (int j = ; j <= tol; j++)
if (f[r][j] - f[l - ][j]) ans++;
putnum (ans);
}
return ;
}

可是在加上了读入和输出优化和依旧超时!

2.

把所有询问存下来,并按照l由小到大的顺序依次回答。当左端点为t时,考虑一个数组b[],若b[i]=1则表示a[i]在a[t]到a[i-1]都没出现过,否则b[i]=0。
那么任意一个左端点l=t,右端点r的询问都可以查询b[1]到b[r]的和得到答案。这个求区间和的操作可以用树状数组或线段树来解决。
当回答完l=t的询问,要回答l=t+1的询问时,涉及到b[]数组的修改。发现只需要把b[t]由1变0,把b[right[t]]由0变1,其中a[t]右边第一个和它相等的数是a[right[t]],可以预处理出来。这两个修改对于树状数组来说太容易了,然后本题就做完了。
补一句,如果题目要求强制在线,就把树状数组换成可持久化线段树,就搞定了。

时间复杂度可以优化至 O(NlogN+Q)

思路真是太棒了!看完这个我感觉这就是我想要的。

于是再经过无数TLE,优化,TLE,再优化终于AC了,并且只用了234ms!

#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <iostream>
using namespace std; const int INF = ; int b[INF], ans[INF], qhead[INF], qr[INF], skip[INF];
int g[INF], ne[INF], last[INF];
int n, m, tol;
inline void rd (int &xx) {
char ch = getchar();
while (ch < '' || ch > '') ch = getchar();
for (xx = ; ch >= '' && ch <= ''; ch = getchar() )
xx = xx * + (ch - '');
}
char o[];
inline void putnum (int x) {
if (x == ) {putchar (''); return;}
int i;
for (i = ; x != ; i++, x /= ) o[i] = x % + '' ;
for (i--; i >= ; i--) putchar (o[i]);
putchar ();
}
int main() {
rd (n); rd (m);
for (int i = ; i <= n; i++) rd (g[i]);
for (int i = , x; i <= m; i++) {
rd (x), rd (qr[i]);
skip[i] = qhead[x];
qhead[x] = i;
}
for (int i = ; i <= n; i++) {
int t = g[i];
if (last[t] == ) for (int x = i; x <= n; x += x & -x) ++b[x];
ne[last[t]] = i, last[t] = i;
}
for (int i = ; i <= n; i++) {
if (qhead[i])
for (int t = qhead[i]; t; t = skip[t])
for (int x = qr[t]; x > ; x -= x & -x) ans[t] += b[x]; for (int x = i; x <= n; x += x & -x) --b[x];
if (ne[i] != ) for (int x = ne[i]; x <= n; x += x & -x) ++b[x];
}
for (int i = ; i <= m; i++)
putnum (ans[i]); }

感谢回答我问题的 nodgd 和  Hoblovski

记一个问题的AC的更多相关文章

  1. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  2. 记一个常见的ms sql server中取第N条记录的方法

    前言 好好学习,天天向上. 正文 好像也是一个不难的问题,刚视频里看到的,就记一下吧. 下面是表中原始的数据结构,做了一个倒叙排序: select * from Employee order by S ...

  3. 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file

    我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...

  4. 记一个简单的sql查询

    在我们做各类统计和各类报表的时候,会有各种各样的查询要求.条件 这篇主要记录一个常见的统计查询 要求如下: 统计一段时间内,每天注册人数,如果某天没有人注册则显示为0 现在建个简单的表来试试 建表语句 ...

  5. Entity Framework学习笔记——记一个错误解决方式及思路

    继续之前设定的学习目标前,先来一篇小小的外篇.按照第一篇里的配置方式配置好的工程前两天还能正常工作,昨天却突然无法通过Add-Migration命令进行数据库的升级.错误信息如下: System.Da ...

  6. 记一个界面刷新相关的Bug

    今天遇到一个比较有意思的bug, 这里简单记录下. Bug的症状是通过拖拉边框把我们客户端主窗口拖小之后,再最大化,会发现窗口显示有问题, 看起来像是刷新问题, 有些地方显示的不对了. 这里要说明的是 ...

  7. 记一个同时支持模糊匹配和静态推导的Atom语法补全插件的开发过程: 序

    简介 过去的一周,都睡的很晚,终于做出了Atom上的APICloud语法提示与补全插件:apicloud_autocomplete.个中滋味,感觉还是有必要记录下来的.代码基于 GPL-3.0 开源, ...

  8. 记一个eclipse 错误 Undefined variable from import: randrange

    我自己定义了一个random.py   和pev的包含路径一样的 解决办法是: 出现这种问题,可以import 这个模块,print 这个模块

  9. 记一个dynamic的坑

    创建一个控制台程序和一个类库, 在控制台创建一个匿名对象,然后再在类库中访问它,代码如下: namespace ConsoleApplication1 { class Program { static ...

随机推荐

  1. ORACLE软件下载地址

    Oracle Database 11g Release 2 Standard Edition and Enterprise Edition Software Downloads Oracle 数据库 ...

  2. git_share

    linux 环境(192.168.8.58) 1. 生成rsa key $ ssh-keygen 如果你之前没有跑过这个文件, 接受默认选项即可. 这样你会在 ~/.ssh/下看到 id_rsa和id ...

  3. 汇编学习笔记(14)BIOS对键盘输入的处理

    字符的处理 键盘输入的字符一般由int9中断例程从60h端口中读取,并存放在键盘缓冲区中,由int16h例程从键盘缓冲区中读取相应字符,CPU对键盘输入a.shift_a的处理过程如下 1.一开始没有 ...

  4. Distinct Subsequences——Leetcode

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  5. CImg 读取jpg, png ,tif 等格式失败解决方案

    CImg homepage :http://cimg.sourceforge.net CImg 给出的一个简单的示例:http://cimg.sourceforge.net/reference/gro ...

  6. Hibernate(三)Hibernate 配置文件

    在上次的博文Hibernate(二)Hibernate实例我们已经通过一个实例的演示对Hibernate 的基本使用有了一个简单的认识,这里我们在此简单回顾一下Hibernate框架的使用步骤. Hi ...

  7. CMS收集器

    CMS收集周期 CMS并非没有暂停,而是用两次短暂停来替代串行标记整理算法的长暂停,它的收集周期是这样:初始标记(CMS-initial-mark) -> 并发标记(CMS-concurrent ...

  8. DES加密后get获取url参数无法解密问题

    参考:http://www.cnblogs.com/lori/archive/2011/09/08/2170979.html 问题,就是URL编码问题,如果不对URL进行编码直接加码,那么在解码时,如 ...

  9. Android关于ListView中item与控件抢夺焦点的那些事

    在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button或者 ...

  10. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享 注:本节阅读需要有MVC 自定义验证的基础,否则比较吃力 一直以来表单的验证都是不可 ...