题目链接:HDU6703 Array
Array
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
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.
InputThe 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.
Sample Input
3 5 9 4 3 1 2 5 2 1 1 2 2 2 2 6 7 2 1 3 2 6 3 2 0 4 1 5 2 3 7 2 4 3 10 6 1 2 4 6 3 5 9 10 7 8 2 7 2 1 2 2 0 5 2 11 10 1 3 2 3 2 10 10 9 7 5 3 4 10 6 2 1 8 1 10 2 8 9 1 12 2 15 15 1 12 2 1 3 1 9 1 12 2 2 2 1 9
Sample Output
1 5 2 2 5 6 1 6 7 3 11 10 11 4 8 11
Hint
note: After the generation procedure ,the instructions of the first test case are : 2 1 1, in format 2 and r=1 , k=1 2 3 3, in format 2 and r=3 , k=3 2 3 2, in format 2 and r=3 , k=2 2 3 1, in format 2 and r=3 , k=1 2 4 1, in format 2 and r=4 , k=1 2 5 1, in format 2 and r=5 , k=1 1 3 , in format 1 and pos=3 2 5 1, in format 2 and r=5 , k=1 2 5 2, in format 2 and r=5 , k=2 the instructions of the second test case are : 2 7 2, in format 2 and r=7 , k=2 1 5 , in format 1 and pos=5 2 7 2, in format 2 and r=7 , k=2 2 8 9, in format 2 and r=8 , k=9 1 8 , in format 1 and pos=8 2 8 9, in format 2 and r=8 , k=9 the instructions of the third test case are : 1 10 , in format 1 and pos=10 2 8 9 , in format 2 and r=8 , k=9 1 7 , in format 1 and pos=7 2 4 4 , in format 2 and r=4 , k=4 1 8 , in format 1 and pos=8 2 5 7 , in format 2 and r=5 , k=7 1 1 , in format 1 and pos=1 1 4 , in format 1 and pos=4 2 10 10, in format 2 and r=10 , k=10 1 2 , in format 1 and pos=2
题意:找出[k,n+1]之间坐标大于r的最小值
分析:权值线段树维护区间坐标最大值,update指向n+1,query求值,find二分剪枝的思想,左边找不到去右边
#include
#define lson rt<<1
#define rson rt<<1|1
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2e5+100;
int n,m,ans;
int a[maxn],pos[maxn];
struct node{int l,r,p;} tree[maxn<<2];
void pushup(int rt) {tree[rt].p=max(tree[lson].p,tree[rson].p);}
void build(int rt,int l,int r)
{
tree[rt].l=l;tree[rt].r=r;
if(l==r)
{
tree[rt].p=pos[l];
return ;
}
int mid=(l+r)>>1;
build(lson,l,mid);build(rson,mid+1,r);
pushup(rt);
}
void update(int rt,int num)
{
if(numtree[rt].r) return ;
if(tree[rt].l==tree[rt].r)
{
tree[rt].p=n+1;
return ;
}
update(lson,num);update(rson,num);
pushup(rt);
}
void find(int rt,int rr)
{
if(tree[lson].p>rr) find(lson,rr);
else if(tree[rson].p>rr) find(rson,rr);
if(tree[rt].p>rr && tree[rt].l==tree[rt].r) ans=min(ans,tree[rt].l);
}
void query(int rt,int ql,int qr,int rr)
{
if(ql<=tree[rt].l && tree[rt].r<=qr)
{
find(rt,rr);
return;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
if(ql<=mid) query(lson,ql,qr,rr);
if(qr>mid) query(rson,ql,qr,rr);
}
void rua()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]]=i;
pos[n+1]=n+1;
build(1,1,n+1);
ans=0;
while (m--)
{
int op;scanf("%d",&op);
if(op==1)
{
int kk;scanf("%d",&kk);kk^=ans;
update(1,a[kk]);
}
else
{
int r,k;scanf("%d%d",&r,&k);r^=ans;k^=ans;
ans=INF;
query(1,k,n+1,r);
printf("%d\n",ans);
}
}
return ;
}
int main()
{
int t;scanf("%d",&t);
while(t--) rua();
return 0;
}