记一个问题的AC
今天突然做一道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的更多相关文章
- 记一个社交APP的开发过程——基础架构选型(转自一位大哥)
记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...
- 记一个常见的ms sql server中取第N条记录的方法
前言 好好学习,天天向上. 正文 好像也是一个不难的问题,刚视频里看到的,就记一下吧. 下面是表中原始的数据结构,做了一个倒叙排序: select * from Employee order by S ...
- 记一个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 ...
- 记一个简单的sql查询
在我们做各类统计和各类报表的时候,会有各种各样的查询要求.条件 这篇主要记录一个常见的统计查询 要求如下: 统计一段时间内,每天注册人数,如果某天没有人注册则显示为0 现在建个简单的表来试试 建表语句 ...
- Entity Framework学习笔记——记一个错误解决方式及思路
继续之前设定的学习目标前,先来一篇小小的外篇.按照第一篇里的配置方式配置好的工程前两天还能正常工作,昨天却突然无法通过Add-Migration命令进行数据库的升级.错误信息如下: System.Da ...
- 记一个界面刷新相关的Bug
今天遇到一个比较有意思的bug, 这里简单记录下. Bug的症状是通过拖拉边框把我们客户端主窗口拖小之后,再最大化,会发现窗口显示有问题, 看起来像是刷新问题, 有些地方显示的不对了. 这里要说明的是 ...
- 记一个同时支持模糊匹配和静态推导的Atom语法补全插件的开发过程: 序
简介 过去的一周,都睡的很晚,终于做出了Atom上的APICloud语法提示与补全插件:apicloud_autocomplete.个中滋味,感觉还是有必要记录下来的.代码基于 GPL-3.0 开源, ...
- 记一个eclipse 错误 Undefined variable from import: randrange
我自己定义了一个random.py 和pev的包含路径一样的 解决办法是: 出现这种问题,可以import 这个模块,print 这个模块
- 记一个dynamic的坑
创建一个控制台程序和一个类库, 在控制台创建一个匿名对象,然后再在类库中访问它,代码如下: namespace ConsoleApplication1 { class Program { static ...
随机推荐
- 多台Mac电脑使用一个apple开发者账号
直接从已安装好的机器上导出私有密钥的,具体方法如下: Xcode的organizer的IPHONE DEVELOPMENT --->Developer Profile里自带的Export和Imp ...
- vijosP1071 新年趣事之打牌
vijosP1071 新年趣事之打牌 链接:https://vijos.org/p/1071 [思路] 01背包+路径输出. 用d[][]记录[][]可转移的数目,>=2则输出-1,0输出0,否 ...
- sql2005中如何启用SA账号
如下图
- redux-applyMiddleware实现理解+自定义中间件
前言: 终于好好理解了middleware.... 1.redux middleware提供的是位于 action 被发起之后,到达 reducer 之前的扩展点. redux通过store.disp ...
- .htaccess文件的妙用
.htaccess是Apache HTTP Server系统级别的配置文件,通常用来实现主机本身以外的一些功能的,比如说重定向.Gzip.以及访问限制等等………… 1.重定向(301跳转) 相信这个功 ...
- vijos1055 奶牛浴场
挺好的一道题呢 O(n^2)或者O(wh) #include<cstdio> #include<cstring> #include<cstdlib> #includ ...
- 【Android - 框架】之Glide的使用
一.Glide简介: Glide是Google官方推荐的一个图片加载和缓存的开源库,它不仅能实现平滑的图片列表滚动效果,还支持远程图片的获取.大小调整和展示,并且可以加载GIF图片.Glide相比与U ...
- 设置UWP程序自启动(Automate launching Windows 10 UWP apps)
在开发UWP程序的过程中,有时候需要设置程序的自启.本人实现的步骤如下: 1.在VS中激活Protocol (Package.appxmanifest --> Declarations --&g ...
- [置顶] Array ArrayList LinkList的区别剖析
这是一个面试中我们经常被问到的问题 Array.ArrayList.LinkList之间的区别:Array.ArrayList.LinkList均属于泛型的范畴,都用来存放元素,主要区别是Array是 ...
- 关于GCC的理解——On the understanding of the GCC
GCC 有超过100个的编译选项可用. 这些选项中的许多你可能永远都不会用到, 但一些主要的选项将会频繁用到. 很多的 GCC 选项包括一个以上的字符. 因此你必须为每个选项指定各自的连字符, 并且就 ...