用主席树写起来跑的快一点,而且也很傻比,二分答案,即二分那个半径就行

主席树求的是区间<=k的个数

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
int a[maxn],n,m; struct Node{int lc,rc,v;}t[maxn*];
int rt[maxn],tot;
int update(int last,int l,int r,int pos){
int now=++tot;
t[now]=t[last];
t[now].v++;
if(l==r)return now;
int m=l+r>>;
if(pos<=m)
t[now].lc=update(t[last].lc,l,m,pos);
else t[now].rc=update(t[last].rc,m+,r,pos);
return now;
}
int query(int st,int ed,int L,int R,int l,int r){
if(L>R)return ;
if(L<=l && R>=r)return t[ed].v-t[st].v;
int m=l+r>>,res=;
if(L<=m)res+=query(t[st].lc,t[ed].lc,L,R,l,m);
if(R>m)res+=query(t[st].rc,t[ed].rc,L,R,m+,r);
return res;
}
int build(int l,int r){
int now=++tot;
t[now].lc=t[now].rc=t[now].v=;
if(l==r)return now;
int m=l+r>>;
t[now].lc=build(l,m);
t[now].rc=build(m+,r);
return now;
}
void init(){
memset(rt,,sizeof rt);
memset(t,,sizeof t);
tot=;
} int main(){
int t;cin>>t;
while(t--){
init();
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
rt[]=build(,n);
for(int i=;i<=n;i++)
rt[i]=update(rt[i-],,,a[i]); int ans=,l,r,p,k;
while(m--){
scanf("%d%d%d%d",&l,&r,&p,&k);
l^=ans,r^=ans,p^=ans,k^=ans; int L=,R=,mid;ans=;
while(L<=R){
mid=L+R>>;
int res1=query(rt[l-],rt[r],,mid+p,,);
int res2=query(rt[l-],rt[r],,p-mid-,,);
if(res1-res2>=k)
ans=mid,R=mid-;
else L=mid+;
}
cout<<ans<<'\n';
}
}
}

线段树的话就要模拟一下归并排序的过程,即线段树结点维护的是区间的有序序列

然后还是二分答案,然后查询的是区间[l,r]范围内在[p-mid,p+mid]范围内的数个数,要特别注意查询的方式

     int res1=lower_bound(seg[rt].begin(),seg[rt].end(),v1)-seg[rt].begin();
int res2=upper_bound(seg[rt].begin(),seg[rt].end(),v2)-seg[rt].begin();//上界一定要用upper_bound!
return res2-res1;
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define maxn 100005
int n,k,l,r,ans,p,m,a[maxn]; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
vector<int>seg[maxn<<];
void pushup(int rt){
int s=seg[rt<<].size(),t=seg[rt<<|].size(),i=,j=;
while(i!=s && j!=t){
if(seg[rt<<][i]<=seg[rt<<|][j])
seg[rt].push_back(seg[rt<<][i]),i++;
else seg[rt].push_back(seg[rt<<|][j]),j++;
}
while(i!=s){
seg[rt].push_back(seg[rt<<][i]);
i++;
}
while(j!=t){
seg[rt].push_back(seg[rt<<|][j]);
j++;
}
} void build(int l,int r,int rt){
seg[rt].clear();
if(l==r){
seg[rt].push_back(a[l]);return;
}
int m=l+r>>;
build(lson);build(rson);
pushup(rt);
}
int query(int L,int R,int v1,int v2,int l,int r,int rt){
if(L<=l && R>=r){
int res1=lower_bound(seg[rt].begin(),seg[rt].end(),v1)-seg[rt].begin();
int res2=upper_bound(seg[rt].begin(),seg[rt].end(),v2)-seg[rt].begin();
return res2-res1;
}
int m=l+r>>,res=;
if(L<=m)res+=query(L,R,v1,v2,lson);
if(R>m)res+=query(L,R,v1,v2,rson);
return res;
} int judge(int mid){
int res=;//查找半径是mid
res=query(l,r,p,p+mid,,n,);
if(res>=k)return ;
res+=query(l,r,p-mid,p-,,n,);
if(res>=k)return ;
return ;
} int main(){
int t;cin>>t;
while(t--){
n=k=l=r=ans=p=m=; scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
build(,n,); while(m--){
scanf("%d%d%d%d",&l,&r,&p,&k);
l^=ans,r^=ans,p^=ans,k^=ans;
int L=,R=,mid;
ans=;
while(L<=R){//二分半径
mid=L+R>>;
if(judge(mid))
ans=mid,R=mid-;
else L=mid+;
}
cout<<ans<<'\n';
}
}
}

主席树/线段树模拟归并排序+二分答案(好题)——hdu多校第4场08的更多相关文章

  1. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  2. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  3. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  4. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  5. [CSP-S模拟测试]:树(树上上升序列+主席树+线段树)

    题目传送门(内部题78) 输入格式 第一行输入两个整数$n,q$,表示节点数和询问数. 第二行输入$n$个整数$w_i$,表示第$i$个点的智商. 第三行至第$n+1$行每行输入两个数$x,y$,表示 ...

  6. BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...

  7. EC Round 33 F. Subtree Minimum Query 主席树/线段树合并

    这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...

  8. POJ2104 K-th Number 不带修改的主席树 线段树

    http://poj.org/problem?id=2104 给定一个序列,求区间第k小 通过构建可持久化的点,得到线段树左儿子和右儿子的前缀和(前缀是这个序列从左到右意义上的),然后是一个二分的ge ...

  9. Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6471  Solved: 2697[Su ...

随机推荐

  1. Tomcat 在IE中下载rar文件直接以乱码方式打开解决方案

    这几天一直很纳闷,在Tomcat部署的网站中的下载文件中,如果文件是rar类型的,一点击下载rar文件就直接打开,并且出现乱码,右键另存为浏览器也是默认为html格式,一直以为是浏览器IE的问题,后来 ...

  2. Shiro学习(11)缓存机制

    Shiro提供了类似于spring的Cache抽象,即Shiro本身不实现Cache,但是对Cache进行了又抽象,方便更换不同的底层Cache实现.对于Cache的一些概念可以参考我的<Spr ...

  3. ORACLE动态sql在存储过程中出现表或视图不存在的解决方法

    Oracle动态sql在存储过程中出现表或视图不存在的解决方法 CREATE OR REPLACE PROCEDURE P_test is strsql varchar2(2000); BEGIN   ...

  4. delphi 文件分割与合并

    流的使用分割与合并文件的函数 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  5. tomcat源码分析一之getCanonicalFile和getAbsolutePath的区别

    最近在看tomcat源码 1.getPath(): 返回定义时的路径,(就是你写什么路径,他就返回什么路径) 2.getAbsolutePath(): 返回绝对路径,但不会处理“.”和“..”的情况 ...

  6. 使用java.util.Properties工具制作自定义访问配置文件信息

    import ch.qos.logback.classic.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; im ...

  7. PAT_A1038#Recover the Smallest Number

    Source: PAT A1038 Recover the Smallest Number (30 分) Description: Given a collection of number segme ...

  8. 20140610 PP中可以绘制表格;PPT组合之后再加效果

    PPT绘制表格(行人检测的cell和block) 动画:组合之后再加效果

  9. zabbix4.0自动注册实践

    共分为两个步骤: 1.主机zabbix_agent客户端的配置文件 2.主机zabbix_server网页端的自动注册配置 zabbix_agent配置文件 Server=192.168.100.15 ...

  10. 2018 最新 spring boot 整合 swagger2 (swagger2 版本 2.8.0)

    好久没上了, 看到又有人回复了. 我就来修改一下. 修改时间  2018年5月16日 这回给你上全新版本. 至发稿时间,所有的包都是新版. 注意: 高版本需要添加  jaxb-api 包, 否则会报错 ...