【CF840D】Destiny

题意:给你一个长度为n的序列,q次询问,每次指定l r k,求[l,r]中出现次数$>\frac {r-l+1} k$的所有数中最小的那个数。

$n,q\le 3\times 10^5,a_i\le n,2\le k \le 5$

题解:考虑分治。对于每次询问,我们将整个序列分成[1,mid]和(mid,n]两部分,要么询问段与mid,mid+1有交点,要么询问段完全位于两边的某一段中,这种情况我们可以递归下去处理。

有一个显然的结论,就是我们将一个区间任意分成两部分,则出现次数最多的k个数要么是左面出现次数最多的k个数,要么是右面出现次数最多的k个数。

我们可以先预处理出:对于每个可能被分成的区间(其实就是线段树上的节点),它的mid往左延伸一些长度,对应的区间中出现次数最多个k个数。即区间[l,mid],[l+1,mid],[l+2,mid]...[mid,mid]的答案。这个从右往左扫一遍很容易得出。再预处理出[mid+1,mid+1],[mid+1,mid+2]...[mid+1,r]的答案。询问时直接拿出这两段区间,然后把2k个数都拿出来,全都在vector上二分一下统计真实的出现次数即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=300010;
int n,m,now,ans;
int cnt[maxn],tim[maxn],val[maxn];
struct node
{
int v[5];
int & operator [] (const int &a) {return v[a];}
}t;
vector<node> ls[maxn<<2],rs[maxn<<2];
vector<int> p[maxn];
bool cmp(const int &a,const int &b) {return (cnt[a]==cnt[b])?(a<b):(cnt[a]>cnt[b]);}
void build(int l,int r,int x)
{
int i,j,mid=(l+r)>>1;
now++;
memset(t.v,0,sizeof(t.v));
for(i=mid;i>=l;i--)
{
if(tim[val[i]]!=now) tim[val[i]]=now,cnt[val[i]]=0;
cnt[val[i]]++;
for(j=0;j<5;j++) if(t[j]==val[i]) break;
if(j==5&&cmp(val[i],t[4])) t[4]=val[i];
for(j=4;j>0;j--) if(cmp(t[j],t[j-1])) swap(t[j-1],t[j]);
ls[x].push_back(t);
}
now++;
memset(t.v,0,sizeof(t.v));
for(i=mid+1;i<=r;i++)
{
if(tim[val[i]]!=now) tim[val[i]]=now,cnt[val[i]]=0;
cnt[val[i]]++;
for(j=0;j<5;j++) if(t[j]==val[i]) break;
if(j==5&&cmp(val[i],t[4])) t[4]=val[i];
for(j=4;j>0;j--) if(cmp(t[j],t[j-1])) swap(t[j-1],t[j]);
rs[x].push_back(t);
}
if(l==r) return ;
build(l,mid,lson),build(mid+1,r,rson);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
//freopen("cf840D.in","r",stdin);
n=rd(),m=rd();
int i,j,a,b,c,l,r,mid,x;
for(i=1;i<=n;i++) val[i]=rd(),p[val[i]].push_back(i);
build(1,n,1);
for(i=1;i<=m;i++)
{
a=rd(),b=rd(),c=rd(),ans=1<<30;
l=1,r=n,x=1;
while(1)
{
mid=(l+r)>>1;
if(a<=mid+1&&b>=mid)
{
now++;
if(a<=mid)
{
t=ls[x][mid-a];
for(j=0;j<c;j++)
{
if(tim[t[j]]!=now) tim[t[j]]=now,cnt[t[j]]=0;
if(c*(upper_bound(p[t[j]].begin(),p[t[j]].end(),b)-lower_bound(p[t[j]].begin(),p[t[j]].end(),a))>b-a+1) ans=min(ans,t[j]);
}
}
if(b>mid)
{
t=rs[x][b-mid-1];
for(j=0;j<c;j++)
{
if(tim[t[j]]!=now) tim[t[j]]=now,cnt[t[j]]=0;
if(c*(upper_bound(p[t[j]].begin(),p[t[j]].end(),b)-lower_bound(p[t[j]].begin(),p[t[j]].end(),a))>b-a+1) ans=min(ans,t[j]);
}
}
break;
}
if(b<mid) r=mid,x=lson;
else l=mid+1,x=rson;
}
if(ans==1<<30) puts("-1");
else printf("%d\n",ans);
}
return 0;
}//5 3 1 2 1 3 2 2 5 3 1 2 3 5 5 2

【CF840D】Destiny 分治(线段树)的更多相关文章

  1. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  2. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  3. 【BZOJ4372】烁烁的游戏 动态树分治+线段树

    [BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...

  4. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...

  5. 【bzoj3730】震波 动态点分治+线段树

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  6. 洛谷T44252 线索_分治线段树_思维题

    分治线段树,其实就是将标记永久化,到最后再统一下传所有标记. 至于先后顺序,可以给每个节点开一个时间戳. 一般地,分治线段树用于离线,只查询一次答案的题目. 本题中,标记要被下传 222 次. Cod ...

  7. 2019ICPC上海网络赛A 边分治+线段树

    题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 解法:边分治+线段树 首先我们将所有的点修改和边修改都存在对应的边里面. 然后 ...

  8. [BZOJ1018][SHOI2008]堵塞的交通traffic 时间分治线段树

    题面 介绍一种比较慢的但是好想的做法. 网上漫天的线段树维护联通性,然后想起来费很大周折也很麻烦.我的做法也是要用线段树的,不过用法完全不同. 这个东西叫做时间分治线段树. 首先我们建一个\(1..m ...

  9. 牛客多校第三场 G Removing Stones(分治+线段树)

    牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...

随机推荐

  1. 你可能不知道UED和UCD

    我们都知道UI是User Interface,即它的本意是用户界面,从字面上看是用户和界面组成,实际上还包括用户与界面之间的交互关系.UI最初对大家来说只是一个名词,它代表一些界面.当然重点还是是UI ...

  2. C语言的基本数据类型长度

    PS:以下内容是在Xcode的编辑器64位环境下的测试结果,网上有关于64位和32位各数据类型存在的差异,请自行online search. main.m #import <Foundation ...

  3. 在swift中使用线程休眠

    C#和php都有sleep让线程休眠指定时间后再继续执行后面的代码,swift中应该如何呢?首先,找一下objective-c版本是怎么做的 [self performSelector:@select ...

  4. 安装oh my zsh和git插件

    http://macshuo.com/?p=676   --安装oh my zsh http://www.jianshu.com/p/9189eac3e52d https://github.com/r ...

  5. Http Cookie Manager、session

     1. JMeter Http Cookie Manager的作用: (1)自动管理 (2)象浏览器一样的存储和发送Cookie.如果你请求一个站点,然后他的Response中包含Cookie,Coo ...

  6. 怎么解决BarTender因为未检测到IIS安装失败的问题

    个别小伙伴在安装BarTender条码标签设计软件的时候,遇到“未检测到IIS,无法安装BarTender Web Print Server配套程序”导致安装失败的问题,本文小编给大家分享解决BarT ...

  7. python日志,支持彩色打印和文件大小切片写入和写入mongodb

    1.项目中使用了自定义的ColorHandler和MongoHandler,使用了内置的RotatingFileHandler和三方库的ConcurrentRotatingFileHandler. 支 ...

  8. Linux下tomcat无法启动

    场景:干净的tomcat,刚解压 1 通过./startup.sh,提示启动成功,但查看没有日志 2 通过netstat -tln查看端口,发现找不到8080 3 通过./catalina.sh ru ...

  9. SpringMVC由浅入深day01_13springmvc和struts2的区别_14问题

    13 springmvc和struts2的区别 1.springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发, ...

  10. Windows 7 无密码文件共享

    Windows7中创建无密码的文件共享的几个步骤: 在“控制面板\所有控制面板项\网络和共享中心\高级共享设置”开启“关闭密码保护共享”和“启用文件和打印机共享”.关闭密码保护共享的操作会启用Gues ...