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. 计算机考研复试真题 N阶楼梯上楼问题

    题目描述 N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式.(要求采用非递归) 输入描述: 输入包括一个整数N,(1<=N<90). 输出描述: 可能有多组测试数据,对于每组数据 ...

  2. 【LeetCode】365.水壶问题

    题目描述 解题思路 思路一:裴蜀定理-数学法 由题意,每次操作只会让桶里的水总量增加x或y,或者减少x或y,即会给水的总量带来x或y的变化量,转为数字描述即为:找到一对整数a,b使得下式成立: ax+ ...

  3. 【分布式锁的演化】终章!手撸ZK分布式锁!

    前言 这应该是分布式锁演化的最后一个章节了,相信很多小伙伴们看完这个章节之后在应对高并发的情况下,如何保证线程安全心里肯定也会有谱了.在实际的项目中也可以参考一下老猫的github上的例子,当然代码没 ...

  4. 【RAC】10grac添加节点,详细步骤

    RAC物理结构 现在的RAC环境是二个节点: dbp,dbs, 这个实验就是添加节点dbi. dbp,dbs和dbi节点的信息规划如下: 服务器主机名 dbp dbs dbi 公共IP地址(eth0) ...

  5. 09--Docker 安装tomcat9

    1.在hub.docker.com中获取tomcat拉取地址 docker pull tomcat:9.0.41-jdk8-corretto 2.查看Dockerfile 中WORKDIR 为/use ...

  6. springmvc 字符串转日期格式

    http://www.mamicode.com/info-detail-2485490.html

  7. centos7下 开启/关闭/查看firewall运行状态命令

    1.开启防火墙:systemctl start firewalld.service [root@localhost bin]# systemctl start firewalld.service [r ...

  8. const关键字:终于拥有真正的常量声明语句

    本文首发于个人网站:const关键字:终于拥有真正的常量声明语句 你好,今天大叔想和你唠扯唠扯 ES6 新增的关键字 -- const.在说 const 关键字之前,大叔先和你唠唠大叔自己对 cons ...

  9. Sgu149 Computer Network

    Sgu149 Computer Network 题目描述 给你一棵N(N<=10000)个节点的树,求每个点到其他点的最大距离. 不难想到一个节点到其他点的最大距离为:max(以它为根的子树的最 ...

  10. 欢迎来到 ZooKeeper 动物世界

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费有趣.入门级的 ZooKeeper 开源教程,面向有编程基础的新手. Zo ...