\(\\\)

Description


原题题面太过混乱出题人语文凉凉

给出一个长为 \(n\) 的数列 \(A\) ,多次询问:

对于一个区间 \([L_i,R_i]\),把区间内的所有数最少划分成多少个数集,使得每一个集合内没有相同元素。

  • \(A_i\le 10^9,n,m\le 2\times 10^5\)

\(\\\)

Solution


题目的模型很容易转化成区间众数问题。

莫队求解区间众数。

首先数据范围是假的,离散化之后就开的下桶了。

对于区间扩张,肯定是加一下桶,然后跟当前答案取 \(max\) 。

问题在于区间缩小时,删除一个数怎么搞。

\(\\\)

开始有一个 too simple 想法,是用堆去维护当前答案区间内所有数出现个数,然后懒惰删除法,每次更新时判断一下堆顶是否正确。

想一想是对的,但是 \(O(N\sqrt NlogN)\) 的复杂度对于 \(2\times 10^5\) 很吃力。

\(\\\)

一个机智的做法。

设 \(cnt[i]\) 表示 \(bkt[x]=i\) 的个数,也就是当前区间里出现次数为 \(i\) 的数的个数。

空间没有问题,因为最多出现数列长度的次数。

这样一来修改就容易了很多,减的时候只需要判断一下,当前数对应的 \(cnt\) 是否 \(>1\) 即可。

注意加减是对 \(cnt\) 和 \(bkt\) 的同时更新。

\(\\\)

Code


  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cctype>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<iostream>
  7. #include<algorithm>
  8. #define N 200000
  9. #define R register
  10. #define gc getchar
  11. using namespace std;
  12. inline int rd(){
  13. int x=0; bool f=0; char c=gc();
  14. while(!isdigit(c)){if(c=='-')f=1;c=gc();}
  15. while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
  16. return f?-x:x;
  17. }
  18. int n,m,ans,bl[N],cnt[N],bkt[N],s[N],tmp[N];
  19. struct Q{int l,r,ans,id;}q[N];
  20. inline bool cmp1(Q x,Q y){
  21. return bl[x.l]==bl[y.l]?x.r<y.r:bl[x.l]<bl[y.l];
  22. }
  23. inline bool cmp2(Q x,Q y){return x.id<y.id;}
  24. inline void add(int p){
  25. --cnt[bkt[s[p]]];
  26. ++cnt[++bkt[s[p]]];
  27. ans=max(ans,bkt[s[p]]);
  28. }
  29. inline void del(int p){
  30. --cnt[bkt[s[p]]];
  31. if(ans==bkt[s[p]]&&!cnt[bkt[s[p]]]) --ans;
  32. ++cnt[--bkt[s[p]]];
  33. }
  34. int main(){
  35. n=rd(); m=rd();
  36. int t=sqrt(n),tot=0;
  37. for(R int i=1,cntt=1;i<=n;++i){
  38. tmp[i]=s[i]=rd();
  39. if(i%t==0) ++cntt;
  40. bl[i]=cntt;
  41. }
  42. sort(tmp+1,tmp+1+n);
  43. for(R int i=1;i<=n;++i){
  44. tmp[++tot]=tmp[i];
  45. while(tmp[i+1]==tmp[i]&&i<=n) ++i;
  46. }
  47. for(R int i=1;i<=n;++i) s[i]=lower_bound(tmp+1,tmp+1+tot,s[i])-tmp;
  48. for(R int i=1;i<=m;++i){
  49. q[i].l=rd(); q[i].r=rd(); q[i].id=i;
  50. }
  51. sort(q+1,q+1+m,cmp1);
  52. bkt[s[1]]=cnt[1]=ans=1;
  53. int nowl=1,nowr=1;
  54. for(R int i=1;i<=m;++i){
  55. while(nowl<q[i].l){del(nowl);++nowl;}
  56. while(nowl>q[i].l){--nowl;add(nowl);}
  57. while(nowr>q[i].r){del(nowr);--nowr;}
  58. while(nowr<q[i].r){++nowr;add(nowr);}
  59. q[i].ans=ans;
  60. }
  61. sort(q+1,q+1+m,cmp2);
  62. for(R int i=1;i<=m;++i) printf("%d\n",-q[i].ans);
  63. return 0;
  64. }

[ Luogu 3709 ] 大爷的字符串题的更多相关文章

  1. luogu 3709 大爷的字符串题 构造 莫队 区间众数

    题目链接 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符\(x\),然后把\(x\)从这个区间中删除,你要维护一个集合S 如果\(S\)为空,你\(r ...

  2. luogu P3709 大爷的字符串题

    二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个 ...

  3. 【luogu P3709 大爷的字符串题】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3709 离散化+区间众数..? #include <iostream> #include < ...

  4. P3709 大爷的字符串题 (莫队)

    题目 P3709 大爷的字符串题 题意:求\([l,r]\)中众数的个数. 解析 维护两个数组: \(cnt[x]\),数\(x\)出现的次数. \(sum[x]\),出现次数为\(x\)的数的个数. ...

  5. AC日记——大爷的字符串题 洛谷 P3709

    大爷的字符串题 思路: 莫队,需开O2,不开50: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20000 ...

  6. P3709 大爷的字符串题(莫队+结论)

    题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...

  7. 洛谷 P3709 大爷的字符串题

    https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个 ...

  8. 洛谷P3709 大爷的字符串题(莫队)

    题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...

  9. P3709 大爷的字符串题(50分)

    题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...

随机推荐

  1. HDU 5666 Segment

    Segment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  2. asp.net下的cookieName

    https://stackoverflow.com/questions/1017144/rename-asp-net-sessionid Add to your web.config:- <sy ...

  3. UIButton常见属性和方法

    一.创建,两种方法: 1. 常规的 initWithFrame UIButton *btn1 = [[UIButton alloc]initWithFrame:CGRectMake(10, 10, 8 ...

  4. CodeForces-607B:Zuma (基础区间DP)

    Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gemstones, the ...

  5. Autolayout UIScrollView

    http://www.cocoachina.com/ios/20141011/9871.html Xcode6中如何对scrollview进行自动布局(autolayout)   Xcode6中极大的 ...

  6. C++初学(1) 简单的加减乘除取余运算代码

    //---------------+-*/%算法---------------------------------------------------------- #include <iost ...

  7. POJ2488【DFS】

    阿西吧,搞清楚谁是行,谁是列啊!!! #include <stdio.h> #include <string.h> #include <math.h> #inclu ...

  8. class JsonItemExporter(BaseItemExporter):

    class JsonItemExporter(BaseItemExporter):这个类的实现和几年前的实现有了点小变化,主要就是是否添加换行

  9. memcached原理及介绍

    memcached是一种缓存技术,在存储在内存中(高性能分布式内存缓存服务器).目的 : 提速.(传统的都是把数据保存在关系型数据库管理系统既RDBMS,客户端请求时会从RDBS中读取数据并在浏览器中 ...

  10. PHP + jquery.validate remote的用法

    [ 转 ] http://www.cnlvzi.com/index.php/Index/article/id/58 最近做验证功能时,用到jquery.validate.js中的remote远程验证方 ...