题目大意:
  给你一个长度为$n(n\le40000)$的数列$\{a_i\}(1\le a_i\le n)$,给出$m(m\le40000)$次询问,每次给出$l,r,k_1,k_2$询问区间$[l,r]$中出现次数第$k_1$小的数中第$k_2$小的数是多少?

思路:
  运用莫队算法离线处理所有询问,分块维护数列中每个数的出现次数。考虑如何维护出现次数的出现次数以及出现次数相同的数。同样采用分块,先预处理出对于某一种出现次数,所有可能的数,再将其离散化,对于离散化后的数分块维护。由于题目空间限制只有24M,因此需要手写内存池或者使用vector,可以证明离散化以后的数组空间复杂度是$O(n)$的。这样时间复杂度$O(m\sqrt n)$,空间复杂度是$O(n+m)$。

 #include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=;
int n,a[N],b[N],block,ans[M],cnt[N];
struct Query {
int l,r,k1,k2,id;
bool operator < (const Query &another) const {
return l/block<another.l/block||(l/block==another.l/block&&r<another.r);
}
};
Query q[M];
std::vector<int> v[N],rank[N],cnt1,sum1,cnt2[N],sum2[N];
inline void modify(const int &x,const int &p,const int &d) {
cnt2[x][p]+=d;
sum2[x][p/block]+=d;
if(d==&&!cnt1[x]++) sum1[x/block]++;
if(d==-&&!--cnt1[x]) sum1[x/block]--;
}
inline void modify(const int &x,const int &d) {
if(cnt[x]) modify(cnt[x],rank[x][cnt[x]],-);
if(cnt[x]+=d) modify(cnt[x],rank[x][cnt[x]],);
}
inline int solve(const std::vector<int> &c,const std::vector<int> &s,const int &k) {
register int x=,cnt=;
while((cnt+s[x])<k) cnt+=s[x++];
for(register int i=x*block;i<(x+)*block;i++) {
if((cnt+=!!c[i])>=k) return i;
}
}
inline int query(const int &k1,const int &k2) {
const int x=solve(cnt1,sum1,k1);
return v[x][solve(cnt2[x],sum2[x],k2)];
}
int main() {
block=sqrt(n=getint());
for(register int i=;i<=n;i++) {
cnt[a[i]=b[i]=getint()]++;
}
std::sort(&b[],&b[n]+);
for(register int i=;i<=n;i++) {
if(b[i]==b[i-]) continue;
rank[b[i]].resize(cnt[b[i]]+);
for(register int j=;j<=cnt[b[i]];j++) {
rank[b[i]][j]=v[j].size();
v[j].push_back(b[i]);
}
cnt[b[i]]=;
}
for(register int i=;i<=n;i++) {
cnt2[i].resize(v[i].size()+);
sum2[i].resize(cnt2[i].size()/block+);
}
const int m=getint();
for(register int i=;i<m;i++) {
const int l=getint(),r=getint(),k1=getint(),k2=getint();
q[i]=(Query){l,r,k1,k2,i};
}
cnt1.resize(n+);
sum1.resize(n/block+);
std::sort(&q[],&q[m]);
for(register int i=,l=,r=;i<m;i++) {
while(r<q[i].r) modify(a[++r],);
while(l>q[i].l) modify(a[--l],);
while(r>q[i].r) modify(a[r--],-);
while(l<q[i].l) modify(a[l++],-);
ans[q[i].id]=query(q[i].k1,q[i].k2);
}
for(register int i=;i<m;i++) {
printf("%d\n",ans[i]);
}
return ;
}

[BZOJ3920]Yuuna的礼物的更多相关文章

  1. bzoj3920: Yuuna的礼物(莫队+分块套分块)

    思路挺简单的,但是总感觉好难写...码力还是差劲,最后写出来也挺丑的 这题显然是个莫队题,考虑怎么转移和询问... 根据莫队修改多查询少的特点,一般用修改快查询慢的分块来维护.查第$k_1$小的出现次 ...

  2. 【莫队算法】【权值分块】bzoj3920 Yuuna的礼物

    [算法一] 暴力. 可以通过第0.1号测试点. 预计得分:20分. [算法二] 经典问题:区间众数,数据范围也不是很大,因此我们可以: ①分块,离散化,预处理出: <1>前i块中x出现的次 ...

  3. bzoj 3920: Yuuna的礼物

    Description 转眼就要到Karin的生日了!Yuuna她们想为她准备生日礼物!现在有许多礼物被排列成了一个一维序列,每个礼物都有一个价值.Yuuna对这个序列十分感兴趣.因此,你需要多次回答 ...

  4. BZOJ.3920.Yuuna的礼物(莫队 分块套分块 分段离散化)

    题目链接 详细题解:https://www.cnblogs.com/autsky-jadek/p/4376091.html 代码参考自:https://www.cnblogs.com/Sakits/p ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. jQuery动画-圣诞节礼物

    ▓▓▓▓▓▓ 大致介绍 下午看到了一个送圣诞礼物的小动画,正好要快到圣诞节了,就动手模仿并改进了一些小问题 原地址:花式轮播----圣诞礼物传送 思路:动画中一共有五个礼物,他们平均分布在屏幕中,设置 ...

  7. bzoj 3055礼物运送 floyed + 状压DP

    bzoj 3055: 礼物运送 floyed first 设f[i][S]表示取到了S集合中的所有点(不一定是经过的所有点),最后停在了i的最优值. 初始就f[i][{i}] = dis[1][i] ...

  8. Typecast 免费了!献给设计师们的礼物

    TypeCast 让你可以从 Fonts.com.TypeKit.FontDeck 和 Google 这些字体供应和商选择字体,而且能非常方便的比较这些字体使用效果.如果你想获得用户对这些字体效果的反 ...

  9. 【HDU 5835】Danganronpa(分配礼物)

    10种礼物,每种有ai个,每个小朋友分两个礼物,其中普通礼物要求相邻两人的不能一样,求最多分给几个小朋友. sum/2是最多的情况.什么时候发不了那么多,就是当max很大,无论怎么发,都发不完max. ...

随机推荐

  1. day06_04 购物车讲解02

    1.0 补充知识 a,b = [2,3] print(a) print(b) #>>>2 #>>>3 a,b = (2,3) print(a) print(b) # ...

  2. ASP.NET Core [4]: Authentication(笔记)

    原文连接:http://www.cnblogs.com/RainingNight/p/authentication-in-asp-net-core.html 在现代应用程序中,认证已不再是简单的将用户 ...

  3. 孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3

    孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十天. 今天继续学习mongoDB的简单操作, ...

  4. (原) Unreal创建自定义MeshCompoent

    @author:白袍小道 随缘查看 前言: 绘制相关类 MeshCompoent 模型组件 FVertexBuffer 顶点缓冲区封装 FIndexBuffer 顶点索引缓冲区封装 FRHIResou ...

  5. java_链表反转

    定义一个Node节点类 1 public class Node { 2 public int value; 3 public Node next; 4 5 public Node(int value) ...

  6. MySQL 主主同步

    双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换到 ...

  7. [转]Android的网络与通信

    本文转自:http://www.cnblogs.com/qingblog/archive/2012/06/15/2550735.html 第一部分 Android网络基础   Android平台浏览器 ...

  8. HttpClient实现POST参数提交

    HttpClient client = new HttpClient(); //使用FormUrlEncodedContent做HttpContent var content = new FormUr ...

  9. springmvc和struts2的区别(转)

    1.客户端浏览器发出HTTP请求.   2.根据web.xml配置,该请求被FilterDispatcher接收.   3.根据struts.xml配置,找到需要调用的Action类和方法, 并通过I ...

  10. iOS大神班笔记04-View的加载

    iOS开发中一个控制器创建View的过程(注意标注的地方): 1.通过storyboard加载 UIStoryboard的三个方法: + (UIStoryboard *)storyboardWithN ...