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

主席树求的是区间<=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. 40th 要掀桌子么 还是尬坐吧

    今日学习精华:     面向对象编程里面有一句  非常经典的描述:-----通过类实例化一个对象,通过对象调方法-----   注意:对象调用的  方法 ,即 函数一定要有  参数      def  ...

  2. oracle hint 强制索引(转)

    oracle 1.建议建立一个以paytime,id,cost的复合索引.光是在paytime上建立索引会产生很多随机读.2.就算建立了索引,如果你查询的数据量很大的话,也不一定会用索引,有时候全表扫 ...

  3. vue element-ui NavMenu错位问题

    原因:子菜单全部打开后太长超过100% 解决方法:设置只能点击打开当前的菜单

  4. node快速入门

    nodejs是一个方兴未艾的技术,近几年一直活跃在各大论坛.其实nodejs也只是新瓶装旧酒,只是它的一些激进的特性使她显得很神秘.nodejs使用的是JavaScript的语法,所以在学习nodej ...

  5. 【专业的 Markdown 编辑写作软件】MWeb for Mac基本使用教程

    MWeb for Mac是一款专业的 Markdown 编辑写作软件,可以生成MarkDown编辑器和静态博客,在记日记的时候,你可以使用插入图片的功能,使用MWeb软件你可以拖拽或直接粘贴即可插入图 ...

  6. 【leetcode】957. Prison Cells After N Days

    题目如下: There are 8 prison cells in a row, and each cell is either occupied or vacant. Each day, wheth ...

  7. Minimum Snap轨迹规划详解(1)轨迹规划

    一. 轨迹规划是什么? 在机器人导航过程中,如何控制机器人从A点移动到B点,通常称之为运动规划.运动规划一般又分为两步: 1.路径规划:在地图(栅格地图.四\八叉树.RRT地图等)中搜索一条从A点到B ...

  8. 向量vector 容器浅析

    一.什么是vector? 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container).跟任意其它类型容器一样,它能够存放各种类型的对象.可以简单的认为,向量是一个能 ...

  9. (转)Linux下使用system()函数一定要谨慎

    转:http://my.oschina.net/renhc/blog/53580 曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.只是简单的知道用这个函 ...

  10. [Go语言]cgo用法演示

        经历了数十年发展的C语言,各种各样的现成的库已经非常丰富.通过cgo,可以在Go语言中使用C语言代码,充分利用好现有的“轮子”. 本文所有代码,在下述环境中调试通过: Windows 8.1 ...