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. NOIP初赛篇——05计算机语言

    程序 ​ 程序就是一系列的操作步骤,计算机程序就是由人实现规定的计算机完成某项工作的操作步骤.每一步骤的具体内容能够理解的指令来描述,这些指令告诉计算机"做什么"和"怎么 ...

  2. 改进你的c#代码的5个技巧(三)

    本文完全独立于前两篇文章.如果你喜欢它们,我希望你也会喜欢这个.在上一篇文章中,我展示了哪种方法更快,并比较了代码的执行速度.在本文中,我将展示不同代码片段的内存消耗情况.为了显示内存映射和分配图,我 ...

  3. 【Flutter】容器类组件之填充

    前言 Padding可以给其子节点添加填充(留白). 接口描述 class EdgeInsets extends EdgeInsetsGeometry { // 分别指定四个方向的填充 const E ...

  4. Jenkins上实现Python + Jenkins + Allure Report 接口自动化测试持续集成,最终测试报告用allure-report进行展示

    项目介绍 接口功能测试应用:http://www.weather.com.cn/data/cityinfo/<city_code>.html 测试功能:获取对应城市的天气预报 源码:Pyt ...

  5. 【Linux】删除软连接被坑

    ------------------------------------------------------------------------------------------------- | ...

  6. 国人之光:大数据分析神器Apache Kylin

    一.简介 Apache Kylin是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献 ...

  7. SparkStreaming和Kafka基于Direct Approach如何管理offset实现exactly once

    在之前的文章<解析SparkStreaming和Kafka集成的两种方式>中已详细介绍SparkStreaming和Kafka集成主要有Receiver based Approach和Di ...

  8. Mac中安装Git

    Mac 安装git 打开Mac终端输入git命令 如果出现以下代码说明已经安装 usage: git [--version] [--help] [-C <path>] [-c <na ...

  9. JAVA获取当前文件路径this.getClass().getResource方法详细讲解

    public class Test { public void run() { // TODO Auto-generated method stub System.out.println(" ...

  10. std::async的使用总结

    C++98标准中并没有线程库的存在,直到C++11中才终于提供了多线程的标准库,提供了管理线程.保护共享数据.线程间同步操作.原子操作等类.多线程库对应的头文件是#include <thread ...