# 动态区间第k小（主席树+线段树套树状数组）

#include<bits/stdc++.h>
using namespace std;
const int maxn = 6e4 + 10;
int n, q;
struct node{
int L, R;
int sum;
node(){
sum = 0;
}
}Tree[2500010];//线段树的节点
int cnt;
int s[maxn];//树状数组,每个点表示一颗线段树的根节点
int X[maxn], Y[maxn];//辅助数组
int T[maxn];//第i棵线段树的根节点
int a[maxn];//原数组
int H[maxn];//原数组排序之后的数组
int m;//总共不同数的个数，也就是每棵线段树的大小
int l, r;
int k;
void init()
{
cnt = 0;
sort(H, H + m);
m = unique(H, H + m) - H;
}
int Hash(int x)
{
return lower_bound(H, H + m, x) - H;
}
int lowbit(int x)
{
return x&(-x);
}
int build(int l, int r)//建立一棵空树T[0]
{
int f = cnt++;
Tree[f].sum = 0;
if(l == r) return f;
int mid = (l + r)>>1;
Tree[f].L = build(l, mid);
Tree[f].R = build(mid + 1, r);
return f;
}
int insert(int pa, int x, int value, int l, int r)
{
int now = cnt++;
Tree[now].sum = Tree[pa].sum + value;
if(l == r) return now;
int mid = (l + r)>>1;
if(x <= mid)
{
Tree[now].R = Tree[pa].R;
Tree[now].L = insert(Tree[pa].L, x, value, l, mid);
}
else
{
Tree[now].L = Tree[pa].L;
Tree[now].R = insert(Tree[pa].R, x, value, mid + 1, r);
}
return now;

}
void update(int loc, int x, int value)//树状数组更新
{
for(int i = loc; i <= n; i += lowbit(i))
{
s[i] = insert(s[i], x, value, 0, m - 1);
}
}
int get(int loc, int *term)//树状数组求和
{
int ans = 0;
for(int i = loc; i >= 1; i -= lowbit(i))
{
ans += Tree[Tree[term[i]].L].sum;
}
return ans;
}
int query(int L, int R, int k, int l, int r, int *term1, int *term2, int p1, int p2)
{
if(l == r) return l;
int mid = (l + r)>>1;
int d1 = Tree[Tree[p2].L].sum - Tree[Tree[p1].L].sum;
int x1 = get(R, term1);
int x2 = get(L - 1, term2);
int d2 = x1 - x2;
int d = d1 + d2;
if(k <= d)
{
for(int i = R; i >= 1; i -= lowbit(i))
{
X[i] = Tree[X[i]].L;

}
for(int i = L - 1; i >= 1; i -= lowbit(i))
{
Y[i] = Tree[Y[i]].L;
}
return query(L, R, k, l, mid, X, Y, Tree[p1].L, Tree[p2].L);
}
else
{
for(int i = R; i >= 1; i -= lowbit(i))
{
X[i] = Tree[X[i]].R;

}
for(int i = L - 1; i >= 1; i -= lowbit(i))
{
Y[i] = Tree[Y[i]].R;
}
return query(L, R, k - d, mid + 1, r, X, Y, Tree[p1].R, Tree[p2].R);
}

}
int main()
{
//freopen("C:\\Users\\creator\\Desktop\\in.txt","r",stdin) ;
//freopen("C:\\Users\\creator\\Desktop\\out.txt","w",stdout) ;
int Case;
scanf("%d", &Case);
while(Case--)
{
scanf("%d%d", &n, &q);
m = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
H[m++] = a[i];
}
char type[10];
for(int i = 1; i <= q; i++)
{
scanf("%s", type);
if(type[0] == 'Q')
{
}
else
{
}
}
init();
T[0] = build(0, m - 1);
for(int i = 1; i <= n; i++)
{
T[i] = insert(T[i - 1], Hash(a[i]), 1, 0, m - 1);
}
for(int i = 1; i <= n; i++)
{
s[i] = T[0];
}
for(int i = 1; i <= q; i++)
{
{
for(int j = Ask[i].r; j >= 1; j -= lowbit(j))
{
X[j] = s[j];
}
for(int j = Ask[i].l - 1; j >= 1; j -= lowbit(j))
{
Y[j] = s[j];
}
}
else
{
}
}

}
return 0;
}



©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客