Problem Description

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

Moreover, there are m instructions.

Each instruction is in one of the following two formats:

1. (1,pos),indicating to change the value of apos to apos+10,000,000;
2. (2,r,k),indicating to ask the minimum value which is **not equal** to any ai ( 1≤i≤r ) and **not less ** than k.

Please print all results of the instructions in format 2.

Input

The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.

In each test case, there are two integers n(1≤n≤100,000),m(1≤m≤100,000) in the first line, denoting the size of array a and the number of instructions.

In the second line, there are n distinct integers a1,a2,...,an (∀i∈[1,n],1≤ai≤n),denoting the array.
For the following m lines, each line is of format (1,t1) or (2,t2,t3).
The parameters of each instruction are generated by such way :

For instructions in format 1 , we defined pos=t1⊕LastAns . (It is promised that 1≤pos≤n)

For instructions in format 2 , we defined r=t2⊕LastAns,k=t3⊕LastAns. (It is promised that 1≤r≤n,1≤k≤n )

(Note that ⊕ means the bitwise XOR operator. )

Before the first instruction of each test case, LastAns is equal to 0 .After each instruction in format 2, LastAns will be changed to the result of that instruction.

(∑n≤510,000,∑m≤510,000 )

Output

For each instruction in format 2, output the answer in one line.

思路

有两种nlogn的解法 、

其一:用权值线段树维护出现的下标 然后维护一下区间最大值 对于1操作我们可以直接把下标变大 对于操作二我们可以区间查询到底 但是要加上一个判断 就是当前子树的

最大下标是否大于输入的位置。

其二:我们可以同样考虑用权值线段树维护当前的最左位置 这样建立可持久化线段树以后我们就可以解决不修改的查询操作 对于操作一 我们可以考虑用一个set维护 那么对于某一查询要么就是

直接查出来的值要么就是set里面的值 我们选一个最小的即可。

解法一:

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef long long ll;
const ll mod = 1e9+7;
int a[N],po[N];
struct tree{
int l,r,v;
}t[N<<2];
void build(int p,int l,int r){
t[p].l=l; t[p].r=r;
if(l==r){
t[p].v=po[l];
//cout<<t[p].l<<" "<<t[p].r<<" "<<t[p].v<<endl;
return ;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p].v=max(t[p<<1].v,t[p<<1|1].v);
}
void update(int p,int x,int v){
if(t[p].l==t[p].r&&t[p].l==x){
t[p].v=v;
po[t[p].l]=v;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) update(p<<1,x,v);
else update(p<<1|1,x,v);
t[p].v=max(t[p<<1].v,t[p<<1|1].v);
}
int query(int p,int l,int r,int pos){
// cout<<t[p].l<<" "<<t[p].r<<endl;
if(t[p].l==t[p].r){
return t[p].l;
}
int mid=(t[p].l+t[p].r)>>1;
int res;
if(t[p<<1].v>pos){
if(l<=mid) res=query(p<<1,l,r,pos);
if(po[res]>pos) return res;
if(r>mid) res=query(p<<1|1,l,r,pos);
}else{
if(r>mid) res=query(p<<1|1,l,r,pos);
}
return res;
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int t; scanf("%d",&t);
while(t--){
memset(po,0,sizeof(po));
int n,m; scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i),po[a[i]]=i;
po[n+1]=n+1;
a[n+1]=n+1;
build(1,1,n+1);
int lastans=0,ans;
for(int i=1;i<=m;i++){
int op,r,k;
scanf("%d%d",&op,&r);
if(op==1){
r=r^lastans;
//printf("%d\n",a[r]);
update(1,a[r],n+1);
}else{
scanf("%d",&k);
r=r^lastans; k=k^lastans;
//cout<<r<<" "<<k<<" "<<lastans<<endl;
ans=query(1,k,n+1,r);
lastans=ans;
printf("%d\n",ans);
// cout<<ans<<"\n";
}
}
}
}

解法二:

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef long long ll;
const ll mod = 1e7+9;
int a[N],rt[N];
struct tree{
int l,r,v;
int ls,rs;
}t[N<<5];
set<int> s;
int nico=0;
int cnt=0;
void build(int &p,int l,int r){
p=++nico;
t[p].l=l; t[p].r=r;
if(l==r){
t[p].v=l;
return ;
}
int mid=(l+r)>>1;
build(t[p].ls,l,mid);
build(t[p].rs,mid+1,r);
t[p].v=min(t[t[p].ls].v,t[t[p].rs].v);
}
void update(int &p,int last,int x,int v){
p=++cnt;
t[p]=t[last];
if(t[p].l==t[p].r&&t[p].l==x){
t[p].v=v;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) update(t[p].ls,t[last].ls,x,v);
else update(t[p].rs,t[last].rs,x,v);
t[p].v=min(t[t[p].ls].v,t[t[p].rs].v);
}
int query(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].v;
}
int mid=(t[p].l+t[p].r)>>1;
int ans=inf;
if(l<=mid) ans=min(ans,query(t[p].ls,l,r));
if(mid<r) ans=min(ans,query(t[p].rs,l,r));
return ans;
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int t; scanf("%d",&t); while(t--){
s.clear();
int n,m; scanf("%d%d",&n,&m);
build(rt[0],1,n+1);
cnt=nico;
for(int i=1;i<=n;i++){
scanf("%d",a+i);
update(rt[i],rt[i-1],a[i],inf);
}
int lastans=0; int nowans;
for(int i=1;i<=m;i++){
int op,t1,t2;
scanf("%d",&op);
if(op==1){
scanf("%d",&t1);
t1=t1^lastans;
s.insert(a[t1]);
}else{
scanf("%d%d",&t1,&t2);
t1=t1^lastans; t2=t2^lastans;
auto v=s.lower_bound(t2);
if(v!=s.end()){
nowans=min(*v,query(rt[t1],t2,n+1));
}else{
nowans=query(rt[t1],t2,n+1);
}
lastans=nowans;
printf("%d\n",nowans);
}
}
}
}

hdu 6703 array(权值线段树)的更多相关文章

  1. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  2. HDU 6609 离散化+权值线段树

    题意 有一个长度为\(n\)的数组W; 对于每一个\(i\)(\(1<=i<=n\)),你可以选择中任意一些元素W[k] (\(1<=k<i\)),将他们的值改变为0,使得\( ...

  3. Petya and Array (权值线段树+逆序对)

    Petya and Array http://codeforces.com/problemset/problem/1042/D time limit per test 2 seconds memory ...

  4. 2019年CCPC网络赛 HDU 6703 array【权值线段树】

    题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n].有两种操作:1.将pos位置的元素+1e72.查询不属于[1,r]中的最小的>=k的值.强制在线. 题解因为数组中的值唯一 ...

  5. ccpc网赛 hdu6703 array(权值线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=6703 大意:给一个n个元素的数组,其中所有元素都是不重复的[1,n]. 两种操作: 将pos位置元素+1e7 查 ...

  6. HDU 6464 免费送气球 【权值线段树】(广东工业大学第十四届程序设计竞赛)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6464 免费送气球 Time Limit: 2000/1000 MS (Java/Others)    M ...

  7. HDU - 2665 Kth number 主席树/可持久化权值线段树

    题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...

  8. HDU - 5592 ZYB's Premutation (权值线段树)

    题意:给出序列前k项中的逆序对数,构造出这个序列. 分析:使用权值线段树来确定序列元素. 逆序对的数量肯定是递增的,从最后一个元素开始逆向统计,则\(a[i] - a[i-1]\)即位置i之前比位置i ...

  9. hdu 5592 ZYB's Premutation (权值线段树)

    最近在线段树的世界里遨游,什么都能用线段树做,这不又一道权值线段树了么. ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Mem ...

随机推荐

  1. KDiff3 Merge工具的使用 极简教程

    www.swack.cn - 原文链接:KDiff3 Merge工具 1.软件安装 下载链接:KDiff3-64bit-Setup_0.9.98-2.exe 安装KDiff3 git config - ...

  2. LeetCode105 从前序和中序序列构造二叉树

    题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9 ...

  3. 奇技淫巧,还是正统功夫? - Python推导式最全用法

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 python免费学习资 ...

  4. ctfhub技能树—sql注入—UA注入

    手注 打开靶机 查看页面信息 抓取数据包 根据提示注入点在User-Agent文件头中 开始尝试注入 成功查到数据库名 查询数据表名 查询字段名 查询字段信息 成功拿到flag 盲注 测试是否存在时间 ...

  5. Sentry(v20.12.1) K8S 云原生架构探索,JavaScript 性能监控之管理 Transactions

    系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...

  6. Java中的基本数据类型与引用数据类型

    一.基本数据类型 byte.short.int.long(整数类型) float.double(浮点数类型) char(字符型) boolean(布尔类型 ) Java数据大多数存放在堆栈中. 栈区: ...

  7. 输入12V,输出12V的限流芯片

    随着手机充电电流的提升,和设备的多样化,USB限流芯片就随着需求的增加而越来越多,同时为了更好的保护电子设备,需要进行一路或者多路的负载进行限流. USB限流芯片,5V输入 1, PW1502,常使用 ...

  8. 【.NET 与树莓派】矩阵按键

    欢迎收看火星卫视,本期节目咱们严重探讨一下矩阵按键. 所谓矩阵按键,就是一个小键盘(其实一块PCB板),上面有几个 Key(开关),你不按下去的时候,电路是断开的,你按下去电路就会接通.至于说有多少个 ...

  9. C# 正则表达式 -- 复习

    符号解释: \ 特殊的字符,转义 ^ 匹配输入的字符串的开始位置 $ 匹配输入的字符串的结束位置 * 匹配0次或多次,等价于{0,} + 匹配1次或多次,等价于{1,} ? 匹配0次或1次,等价于{0 ...

  10. 大数据系列2:Hdfs的读写操作

    在前文大数据系列1:一文初识Hdfs中,我们对Hdfs有了简单的认识. 在本文中,我们将会简单的介绍一下Hdfs文件的读写流程,为后续追踪读写流程的源码做准备. Hdfs 架构 首先来个Hdfs的架构 ...