题意

给你一个1~n的排列,由两种操作:

1 pos:将a[pos]+10 000 000

2 r k:求大于等于k且不等于a[1~r]的数的最小值。

强制在线。

思路

如果没有1操作,那么我们直接主席树就OK了。

考虑不真正的进行修改,每次1操作就把a[pos]插进set,因为加10 000 000后肯定是大于n的,而k是小于等于n的,所以set里的数是可以用的。要和1r的数都不相同,那么我们用主席树查找区间r+1n+1的大于等于k的最小值即可,为什么是n+1呢,因为k<=n,如果k==n,那么满足条件且最小的数必定是n+1了。修改后的数的值变大了,而k<=n,显然这个修改后的值是对答案无影响的,但原来的值仍然是可以利用的,所以我们可以在set里二分查找第一个大于等于k的数,然后和主席树查到的取个最小值即可。

至于主席树查询的技巧:要剪枝,当sum[v]-sum[u]<=0时,表示这个区间不存在大于等于k的数,直接return inf;先判断是否k<=mid,才能往区间左边走,如果找到满足条件的数了我们就不必再往区间右边找了,因为右边的数肯定比左边大,相当于减了一半的时间。

代码

#include<bits/stdc++.h>
#define mid (l+r)/2
using namespace std; const int N = 1e5+5;
int n, q, sz, num = 0;
int a[N], b[N], T[N];
int sum[N<<5], L[N<<5], R[N<<5],mi[N<<5];
#define inf 0x3f3f3f3f
inline int build(int l, int r)
{
int rt = ++ num;
sum[rt] = 0;
if (l < r)
{
L[rt] = build(l, mid);
R[rt] = build(mid+1, r);
}
return rt;
} inline int update(int pre, int l, int r, int x)
{
int rt = ++ num;
L[rt] = L[pre];
R[rt] = R[pre];
sum[rt] = sum[pre]+1;
if (l < r)
{
if (x <= mid) L[rt] = update(L[pre], l, mid, x);
else R[rt] = update(R[pre], mid+1, r, x);
}
return rt;
} inline int query(int u, int v, int l, int r, int k)
{
if(sum[v]-sum[u]<=0)
return inf;
if(l==r)
return l;
int ans=inf;
if(k<=mid)
ans=min(ans,query(L[u], L[v], l, mid, k));
if(ans==inf)
ans=min(ans,query(R[u], R[v], mid+1, r, k));
// cout<<ans<<endl;
return ans;
}
set<int> s;
int main()
{
int TT;
scanf("%d",&TT);
while(TT--)
{
s.clear();
scanf("%d%d", &n, &q);
num=0;
T[0] = build(1, n+1);
for (int i = 1; i <= n; i ++)
{
scanf("%d", &a[i]);
T[i] = update(T[i-1], 1, n+1, a[i]);
}
T[n+1]=update(T[n],1,n+1,n+1);
int ans=0;
while (q --)
{
int o,x,y;
scanf("%d", &o);
if(o==1)
{
scanf("%d",&x);
x^=ans;
s.insert(a[x]);
// ans=0;
}
else
{
scanf("%d%d",&x,&y);
x^=ans,y^=ans;
// cout<<x<<" "<<y<<endl;
set<int>::iterator it=s.lower_bound(y);
int t=inf;
if(it!=s.end())
t=*it;
// cout<<"t"<<t<<endl;
ans=min(query(T[x],T[n+1],1,n+1,y),t);
printf("%d\n",ans);
}
} }
return 0;
}

2019CCPC网络选拔赛 hdu6703 array(主席树+set)的更多相关文章

  1. 2019ccpc网络赛hdu6703 array(线段树)

    array 题目传送门 解题思路 操作1是把第pos个位置上的数加上\(10^7\),操作2是找到区间[1,r]中没有且大于k的最小的数.注意到k的范围是小于等于n的,且n的范围是\(10^5\),远 ...

  2. hdoj6703 2019 CCPC网络选拔赛 1002 array

    题意 description You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of the ...

  3. hdu6704 2019CCPC网络选拔赛1003 K-th occurrence 后缀数组

    题意:给你一个长度为n的字符串,有q个询问,每次询问一个子串s(l,r)第k次出现的位置,若子串出现次数少于k次输出-1. 解题思路:先把SA跑出来,然后对于每次询问可以由l和rank[]找到l在所有 ...

  4. hdu6704 2019CCPC网络选拔赛1003 K-th occurrence 后缀自动机+线段树合并

    解题思路: fail树上用权值线段树合并求right/endpos集合,再用倍增找到待查询串对应节点,然后权值线段树求第k大. #include<bits/stdc++.h> using ...

  5. HDU6703 array (线段树)

    题意:长为1e5的全排列 有两个操作 把一个数删掉 询问1,r这个区间内 找到一个数大于等于x 且这个数不等于区间内的所有数 题解:建一颗权值线段树 线段树里存值为i的数在原数组中的坐标 维护坐标的最 ...

  6. hdu6075 2019CCPC网络选拔赛1004 path

    题意:给定一个带权有向图,有q组询问,每次询问在有向图的所有路径中,第k小的路径权值 解题思路:因为k最大只有5e4,考虑暴力搜索出前maxk小的路径并用数组记录权值,然后就可以O(1)查询. 具体实 ...

  7. [2019CCPC网络赛][hdu6704]K-th occurrence(后缀数组&&主席树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6704 题意为查询子串s[l...r]第k次出现的位置. 写完博客后5分钟的更新 写完博客才发现这份代码 ...

  8. 2019CCPC网络赛 C - K-th occurrence HDU - 6704(后缀数组+ST表+二分+主席树)

    题意 求区间l,r的子串在原串中第k次出现的位置. 链接:https://vjudge.net/contest/322094#problem/C 思路 比赛的时候用后缀自动机写的,TLE到比赛结束. ...

  9. HDU 6447 - YJJ's Salesman - [树状数组优化DP][2018CCPC网络选拔赛第10题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 Problem DescriptionYJJ is a salesman who has tra ...

随机推荐

  1. JupyterLab安装与配置虚拟环境

    JupyterLab安装: 推荐使用miniconda,相比于anaconda更加简洁,下载连接:https://mirrors.tuna.tsinghua.edu.cn/anaconda/minic ...

  2. 微信扫码登陆,qq登陆,微博登陆等第三方登陆成功后返回原来的页面并进行跳转

    原理很简单,主要是利用到window.open的第二个属性,name 前端: 原来的网页给window命名为 window.name="single" window.open(“第 ...

  3. Thinkphp 模板中 if 嵌套层级过多的问题,嵌套3级就报错,取消层级限制

    解决此问题有两种办法:1.第三层if换成eq或者原生<?php 'abc';>  2.修改Tp核心配置文件 1.第三层if换成eq或者原生<?php 'abc';> 如下图&l ...

  4. 用Docker运行Jenkins自动化构建.NET Core项目

    目标 当代码提交到GitHub后,自动生成构建项目并部署到服务器.接下来介绍一下如何在容器中运行Jenkins,并自动化构建GitHub上的项目,使用自动化构建来解放你的双手. 前置条件 一台已经安装 ...

  5. linux下关闭selinux

    找到 /etc/sysconfig/selinux 文件 修改 SELINUX=enable 使之 SELINUX=disable 重启 reboot

  6. crossover mac如何使用?crossover mac使用教程

    CrossOver Mac 破解版可以在 Mac 上运行成千上万的 Windows 程序,从办公软件.实用工具.游戏到设计软件.CrossOver 19 破解版可以让 Windows 程序和 Mac ...

  7. EF Core 3.0 Preview 9 的2个小坑

    之前我们的数据库服务器使用的是 SQL Server 2008 R2 ,由于从 EF Core 3.0 Preview 6 开始不支持 UseRowNumberForPaging ,只能停留在 EF ...

  8. python面试题及答案 2019

    利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法. 正解1: def trim(s): while s[:1] == ' ': s = s[1:] ...

  9. IT兄弟连 HTML5教程 HTML5的基本语法 如何选择开发工具

    如何选择开发工具 有许多可以编辑网页的软件,事实上你不需要用任何专门的软件来建立HTML页面,你所需要的只是一个文本编辑器(或字处理器),如Office Word.记事本.写字板等.制作页面初学者通常 ...

  10. IT兄弟连 Java语法教程 流程控制语句 分支结构语句4

    4  嵌套if-else条件语句 嵌套if语句是作为另一个if或else语句的目标的if语句.嵌套if语句在程序设计中非常普遍.Java中,关于嵌套if语句需要记住的是,else语句总是和同一代码块中 ...