HDU-6703 array (线段树)
题意
一个长度为n的排列a,\(\forall i\in [1,n] ,1\le a_i \le n\) , m次操作,每次操作:
- (1,pos),把 \(a_{pos}\) 变为\(a_{pos} + 10000000\)
- (2,r,k) ,找到最小的一个值x,使得\(\forall i\in [1,r], x \neq a_i, x\ge k\)
数据范围:
\(1\le n\le 100000,1\le m\le 100000,1\le r\le n,1\le k\le n\)
分析
观察每个数的值域,都在\([1,n]\) 之间,而k的范围也在\([1,n]\) 之间,所以答案最终只会在\([1,n+1]\) 之间。
操作1会使一个数字\(a_i\)加1e7,而这个数已经远远超过n和k,所以也就代表着\(a_i\)从原序列中被删除了。
由第一条可以知道,每次查询的答案只会在[k,n+1]上,而序列中的数只会在[1,n](进行过1操作的直接删除,不再考虑)。所以我们可以每次查询序列中有没有出现在\([k,n]\) 的数,并且他们的下标是大于r的。如果之前删除过一个数\(x\),那么就把这个下标变成大于n就可以了, 这样对于\(k\le x\) 的情况,\(x\) 所对应的下标都是大于\(r\) 的(也就是把x作为候选答案)
如何维护查询所需要的东西?权值线段树维护区间权值最大下标
- 对于操作1,直接让单点的下标变为n+1
- 对于操作2,找被区间[k,n]的包含的结点,对于这些结点,如果左节点的最大下标大于r,则递归左节点,否则看右结点,如果都没有,就返回n+1(代表答案候选为n+1)。而递归到终点时,看单点维护的下标是否大于r,如果大于,就返回单点的权值,否则返回n+1.
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
int a[N],b[N];
struct SegTree{
int l,r,id;
}t[4*N];
int n,m;
void build(int p,int l,int r){
t[p].l = l;t[p].r = r;
if(l == r){
t[p].id = b[l];
return;
}
int mid = l + r >> 1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].id = max(t[p*2].id,t[p*2+1].id);
}
void change(int p,int x){
if(t[p].l == t[p].r && t[p].l == x){
t[p].id = n+1;return;//删除该数,将维护的下标变为n+1
}
int mid = t[p].l + t[p].r >> 1;
if(x <= mid)change(p*2,x);
else if(x > mid)change(p*2+1,x);
t[p].id = max(t[p*2].id,t[p*2+1].id);
}
int query(int p,int l,int r,int x){
if(t[p].l >= l && t[p].r <= r){//找到被[k,n]完全包含的结点
if(t[p].l == t[p].r){
if(t[p].id > x)
return t[p].l;
return n + 1;
}
if(t[p*2].id > x)return query(p*2,l,r,x);
if(t[p*2+1].id > x)return query(p*2+1,l,r,x);
return n + 1;
}
int mid = t[p].l + t[p].r >> 1;
int res = n+1;
if(mid >= l){
res = query(p*2,l,r,x);
}
if(mid < r){
res = min(res, query(p*2+1,l,r,x));
}
return res;
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)b[i] = 0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[a[i]] = i;//因为时排列,每个a[i]都不一样
}
build(1,1,n);
int res = 0;
while(m--){
int op,x,y;
scanf("%d%d",&op,&x);
if(op == 1){
x ^= res;
change(1,a[x]);
}
else{
scanf("%d",&y);x^=res;y^=res;
res = query(1,y,n,x);
printf("%d\n",res);
}
}
}
return 0;
}
HDU-6703 array (线段树)的更多相关文章
- 2019年CCPC网络赛 HDU 6703 array【权值线段树】
题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- hdu 6703 array(权值线段树)
Problem Description You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- HDU 5877 dfs+ 线段树(或+树状树组)
1.HDU 5877 Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
随机推荐
- 九个最容易出错的 Hive sql 详解及使用注意事项
阅读本文小建议:本文适合细嚼慢咽,不要一目十行,不然会错过很多有价值的细节. 文章首发于公众号:五分钟学大数据 前言 在进行数仓搭建和数据分析时最常用的就是 sql,其语法简洁明了,易于理解,目前大数 ...
- linux find命令用法大全
本文档格式如下,命令说明在命令的上一行,尝试使用 Ctrl+f 组合键快速在页面内搜索. 命令说明 命令 参数起始目录:查找文件的起始目录.实例# 当前目录搜索所有文件,文件内容 包含 &qu ...
- ssh升级以及ssh: symbol lookup error: ssh: undefined symbol: EVP_aes_128_ctr错误处理
1.解压安装openssl包:(不能卸载openssl,否则会影响系统的ssl加密库文件,除非你可以做两个软连接libcryto和libssl) # tar -zxvf openssl-1.0.1.t ...
- js的函数-function
function函数 function的英文是[功能],[数] 函数:职责:盛大的集会的意思 在js里,就是函数的意思.在Java里叫做方法. 定义函数 function fun(参数){ //函数体 ...
- 【Oracle】Oracle中chr()的含义
oracle中chr含义 CHR(10)和 CHR(13)--在oracle都为换行 chr(32)--表示空格 DECLARE v_a VARCHAR2(255); v_b VARCHAR2(255 ...
- bash5.0参考手册
Bash Reference Manual a.summary-letter { text-decoration: none } blockquote.indentedblock { margin-r ...
- centos7安装vsftpd最大的坑
1.检查用户和密码没有错误2.vsftpd.conf配置没有错误3.检查/etc/vsftpd/vsftpd.conf 里面pam_service_name =vsftpd4.终极boss查看vim ...
- linux下删除文件夹及下面所有文件
使用rm -rf 目录名字 命令即可 -r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 rm 不带参数 只能删除文件 rm test.txt mkdir /us ...
- kaggle新手如何在平台学习大神的代码
原创:数据臭皮匠 [导读]Kaggle ,作为听说它很牛X但从未接触过的同学,可能仅仅了解这是一个参加数据挖掘比赛的网站,殊不知Kaggle也会有赛题相关的数据集, 比如我们熟知的房价预测.泰坦尼克 ...
- floating point
记录浮点数的单精度和双精度(IEEE754) 1.单精度(float) 1.定义:单精度占4字节/32位,其中1号位符号位,其次是8位阶码/指数(阶符+阶数),23位尾数(小数). 2.双精度(d ...