看到这个题面,不断加入元素,每次查询第k大,我就立刻想到了平衡树……
然后又不会手码,于是想到了pbds的tree
然后就轻松的码出了30分的代码……
问了别人才知道原来有重复元素,而且pbds的tree是不能插入重复元素的
那么,我们怎么解决呢?
我想到了hash。
我们对每个元素维护一个二元组$\left(x,h\right)$,$x$表示元素本来的值,而$h$是我们通过hash搞出的一个唯一的随机值。
然后对每个u把没加进tree的元素加进去,然后直接利用tree求kth。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <bits/stdc++.h> #include <bits/extc++.h> using namespace std; using namespace __gnu_pbds; struct User{ int x,h; inline bool operator < (const User&p)const{return x!=p.x?x<p.x:h<p.h;} }a[200005]; tree<User,null_type,less<User>,rb_tree_tag,tree_order_statistics_node_update> t; map<int,bool> mp; int m,n,i,u[200005],last=1,hh; inline int Hash(int x){ while(mp[x])x=x+rand(); return x; } int main(){ scanf("%d%d",&m,&n); for (int j=1;j<=m;j++){ scanf("%d",&a[j].x); hh=Hash(a[j].x); a[j].h=hh,mp[hh]=1; } for (int j=1;j<=n;j++)scanf("%d",&u[j]); for (int j=1;j<=n;j++){ for (;last<=u[j];last++)t.insert(a[last]); printf("%d\n",(*t.find_by_order(i++)).x); } }
|