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[ ...
随机推荐
- fastjson复现项目代码
详情请见:https://www.cnblogs.com/yunmuq/p/14268028.html 以下是代码 // FastjsonDemo.java package test; import ...
- Scrapy使用RabbitMQ做任务队列
前言 一个月没更博客了,这个月也搞了不少东西,但是公司对保密性要求挺高,很多东西都没有办法写出来 想来想去,还是写一篇最近写Scrapy中遇到的跳转问题 如果你的业务需求是遇到301/302/303跳 ...
- Laya 踩坑日记-BitmapFont 不显示空格
项目中有用到艺术字,美术通过 bmfont64 将字体导给我了,结果发现在应用上 空格不显示 如图: 今天去深究了一下这个问题,发现是底层没封装好,然后自己改了一下下面是改过的 BitmapFont ...
- 剑指offer 面试题3:数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- mmall商城用户模块开发总结
1.需要实现的功能介绍 注册 登录 用户名校验 忘记密码 提交问题答案 重置密码 获取用户信息 更新用户信息 退出登录 目标: 避免横向越权,纵向越权的安全漏洞 MD5明文加密级增加的salt值 Gu ...
- 使用smartform打印表单
昨天写了个smartform打印表单,在开发完成,在测试机测试OK,传到生产机,出现严重问题!无法打印,干脆就是无法调用打印图形界面,进入SMARTFORM事物,查看这个表单,发现,居然公司的LOGO ...
- 关于SQL Server 镜像数据库快照的创建及使用
从SQL Server 2005 SP 起,SQL 开始支持数据库镜像.它的设计目的是试图为SQL Server 提供一个具有实时性数据同步的灾难恢复技术,即能够提供数据冗余备份,切换起来比较方便.每 ...
- atlas读写分离
Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目.它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug ...
- Django - WebSocket:dwebsocket
Django - WebSocket:dwebsocket 什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换 ...
- linux编译模块,包含了头文件却还是报undifind警告
在编写一个自己写的gadget驱动的时候遇到一个这样的问题,编译的时候报了个警告:WARNING: "usb_composite_register" [-/my_zero.ko] ...