KQUERYO - K-Query Online
no tags
Given a sequence of n numbers a1, a2, …, an and a number of k-queries. A k-query is a triple (i, j, k) (1 ≤ i ≤ j ≤ n). For each k-query (i, j, k), you have to return the number of elements greater than k in the subsequence ai, ai+1, …, aj.
Input
Line 1: n (1 ≤ n ≤ 30000).
Line 2: n numbers a1, a2, …, an (1 ≤ ai ≤ 109).
Line 3: q (1 ≤ q ≤ 200000), the number of k- queries.
In the next q lines, each line contains 3 numbers a, b, c representing a k-query. You should do the following:
i = a xor last_ans
j = b xor last_ans
k = c xor last_ans
After that 1 ≤ i ≤ j ≤ n, 1 ≤ k ≤ 109 holds.
Where last_ans = the answer to the last query (for the first query it’s 0).
Output
For each k-query (i, j, k), print the number of elements greater than k in the subsequence ai, ai+1, …, aj in a single line.
Example
Input:
6
8 9 3 5 1 9
5
2 3 5
3 3 7
0 0 11
0 0 2
3 7 4
Output:
1
1
0
0
2
[Edited by EB]
There are invalid queries. Assume the following:
if i < 1: i = 1
if j > n: j = n
if i > j: ans = 0
題意:給一個序列,q次詢問,求區間內比k大的數
題解:主席樹/歸併樹 入門題
主席樹
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
const int maxn=3e4+5;
int a[maxn],b[maxn];
struct node{
int l;
int r;
int sum;
}nod[maxn<<5];
int root[maxn],tot;
void build(int &rt,int l,int r){
rt=++tot;
nod[rt].sum=0;
if(l==r)return;
int mid=(l+r)>>1;
build(nod[rt].l,l,mid);
build(nod[rt].r,mid+1,r);
}
void update(int &rt,int last,int l,int r,int x){
rt=++tot;
nod[rt].l=nod[last].l;
nod[rt].r=nod[last].r;
nod[rt].sum=nod[last].sum+1;
if(l==r)return;
int mid=(l+r)>>1;
if(mid>=x)update(nod[rt].l,nod[last].l,l,mid,x);
else update(nod[rt].r,nod[last].r,mid+1,r,x);
}
int query(int rt,int l,int r,int l0,int r0){
if(l>=l0&&r<=r0)return nod[rt].sum;
int mid=(l+r)>>1;
int xx=0;
if(mid>=l0)xx+=query(nod[rt].l,l,mid,l0,r0);
if(mid<r0)xx+=query(nod[rt].r,mid+1,r,l0,r0);
return xx;
}
int main ()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=a[i];}
sort(b+1,b+1+n);
int siz=unique(b+1,b+1+n)-(b+1);
build(root[0],1,siz);
for(int i=1;i<=n;i++){
int pos=lower_bound(b+1,b+1+siz,a[i])-b;
update(root[i],root[i-1],1,siz,pos);
}
int q;
scanf("%d",&q);
int x=0;
while(q--){
int l,r,s;
scanf("%d%d%d",&l,&r,&s);
l^=x;
r^=x;
s^=x;
if(l<1)l=1;
if(r>n)r=n;
if(l>r){
printf("0\n");
x=0;
continue;
}
int pos=upper_bound(b+1,b+1+siz,s)-b;
if(pos>siz){printf("0\n");x=0;}
else{
x=query(root[r],1,siz,pos,siz)-query(root[l-1],1,siz,pos,siz);
printf("%d\n",x);
}
}
return 0;
}
歸併樹
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
const int maxn=3e4+5;
int a[maxn];
vector<int>v[maxn<<2];
void merg(vector<int> &v0,vector<int> v1,vector<int> v2){
int t1=0;
int t2=0;
while(t1<v1.size()&&t2<v2.size()){
if(v1[t1]<=v2[t2]){
v0.push_back(v1[t1]);
t1++;
}
else{
v0.push_back(v2[t2]);
t2++;
}
}
while(t1<v1.size()){
v0.push_back(v1[t1]);
t1++;
}
while(t2<v2.size()){
v0.push_back(v2[t2]);
t2++;
}
}
void build(int rt,int l,int r){
if(l==r){
v[rt].push_back(a[l]);
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build((rt<<1)|1,mid+1,r);
merg(v[rt],v[rt<<1],v[(rt<<1)|1]);
}
int query(int rt,int l,int r,int l0,int r0,int k){
if(l>=l0&&r<=r0){return v[rt].size()-(upper_bound(v[rt].begin(),v[rt].end(),k)-v[rt].begin());}
int mid=(l+r)>>1;
int xx=0;
if(mid>=l0)xx+=query(rt<<1,l,mid,l0,r0,k);
if(mid<r0)xx+=query((rt<<1)|1,mid+1,r,l0,r0,k);
return xx;
}
int main ()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){scanf("%d",&a[i]);}
build(1,1,n);
int q;
scanf("%d",&q);
int x=0;
while(q--){
int l,r,s;
scanf("%d%d%d",&l,&r,&s);
l^=x;
r^=x;
s^=x;
if(l<1)l=1;
if(r>n)r=n;
if(l>r){
printf("0\n");
x=0;
continue;
}
x=query(1,1,n,l,r,s);
printf("%d\n",x);
}
return 0;
}