给出一串数字,然后给出两种操作:
1. 1 L V 操作一:把下标为L的点的值替换为 V
2. 2 L R K 操作二:在 [L,R] 区间求第K大
本模板转载自
http://blog.csdn.net/u012860063/article/details/47813079
my code
#include
#include
#include
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 600010;
const int M = 100010;
struct Treap {
int key,wht,count,sz,ch[2];
} tp[N<<4];
int tree[N<<1];
int nodeCount, root;
inline int idx(int l,int r) {
return l+r | l!=r;
}
void init() {
tp[0].sz = 0;
tp[0].wht = -INF;
nodeCount = 0;
root = 0;
}
void update(int x) {
tp[x].sz = tp[tp[x].ch[0]].sz + tp[x].count + tp[tp[x].ch[1]].sz;
}
void rotate(int &x,int t) {
int y=tp[x].ch[t];
tp[x].ch[t]=tp[y].ch[!t];
tp[y].ch[!t]=x;
update(x);
update(y);
x=y;
}
void insert(int &x, int t) {
if(!x) {
x = ++nodeCount;
tp[x].key = t;
tp[x].wht = rand();
tp[x].count = 1;
tp[x].ch[0] = tp[x].ch[1]=0;
}else if(tp[x].key == t)
tp[x].count++;
else {
int k = tp[x].key < t;
insert(tp[x].ch[k],t);
if(tp[x].whtx].ch[k]].wht)
rotate(x,k);
}
update(x);
}
void erase(int &x,int t) {
if(tp[x].key == t) {
if(tp[x].count == 1) {
if(!tp[x].ch[0] && !tp[x].ch[1]) {
x = 0;
return;
}
rotate(x, tp[tp[x].ch[0]].wht < tp[tp[x].ch[1]].wht);
erase(x, t);
}
else tp[x].count--;
}
else erase(tp[x].ch[tp[x].keyx);
}
int select(int x,int t) {
if(!x) return 0;
if(tp[x].key>t) return select(tp[x].ch[0],t);
return tp[x].count + tp[tp[x].ch[0]].sz + select(tp[x].ch[1],t);
}
int a[N], b[N], ord[M][5], tot;
int n, m;
int search(int x) {
int l = 1, r = tot, mid;
while (l<=r) {
mid = (l+r)>>1;
if(b[mid]==x) return mid;
if(b[mid]<x) l = mid+1;
else r = mid-1;
}
}
void treeInsert(int l,int r,int i,int x) {
insert(tree[idx(l,r)],x);
if(l==r) return;
int m=(l+r)>>1;
if(i<=m) treeInsert(l,m,i,x);
else treeInsert(m+1,r,i,x);
}
void treeDel(int l,int r,int i,int x) {
erase(tree[idx(l,r)],x);
if(l==r) return;
int m=(l+r)>>1;
if(i<=m) treeDel(l,m,i,x);
else treeDel(m+1,r,i,x);
}
int query(int l,int r,int x,int y,int k) {
if(l==r) return l;
int m=(l+r)>>1;
int ans=select(tree[idx(l,m)],y) - select(tree[idx(l,m)],x);
if(ans>=k) return query(l,m,x,y,k);
return query(m+1,r,x,y,k-ans);
}
int main() {
while (~scanf("%d",&n)) {
tot = 0;
memset(tree,0,sizeof(tree));
init();
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
b[++tot] = a[i];
}
scanf("%d",&m);
for(int i=1; i<=m; i++) {
int op;
int x,y,c;
scanf("%d",&op);
if(op == 2) {
scanf("%d%d%d",&x,&y,&c);
ord[i][1]=1;
ord[i][2]=x; ord[i][3]=y; ord[i][4]=c;
}else {
scanf("%d%d",&x,&y);
ord[i][1]=2;
ord[i][2]=x; ord[i][3]=y;
b[++tot]=y;
}
}
sort(b+1,b+1+tot);
tot = unique(b+1, b+1+tot) - b;
for(int i=1; i<=n; i++) {
a[i]=search(a[i]);
treeInsert(1,tot,a[i],i);
}
for(int i=1; i<=m; i++) {
if(ord[i][1]==1)
printf("%d\n",b[query(1, tot, ord[i][2]-1, ord[i][3], ord[i][4])]);
else {
treeDel(1, tot, a[ord[i][2]], ord[i][2]);
a[ord[i][2]] = search(ord[i][3]);
treeInsert(1, tot, a[ord[i][2]], ord[i][2]);
}
}
}
return 0;
}