2015-03-16 19:52:57

思路:一道比较裸的插入不断插入数值、删除数值 + 查询第k大的题目。

  (1)对于合并操作,可以采用并查集来维护,并维护一个num值来表示group总数。

  (2)对于查询第k大的操作

    (i)可以用树状数组维护+二分查找来不断逼近第k大

    (ii)可以利用树状数组本身c[]数组的特性来倍增逼近第k大

    (iii)用treap来查询第k大

    (iv)当然还可以用线段树.....

方法1:树状数组+二分

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
21 #define MP(a,b) make_pair(a,b)
22 
23 typedef long long ll;
24 typedef pair<int,int> pii;
25 const int INF = (1 << 30) - 1;
26 const int MAXN = 300010;
27 
28 int N,M,num;
29 int fa[MAXN],sz[MAXN];
30 
31 struct BIT{
32     int c[MAXN];
33     int Lowbit(int x){
34         return x & (-x);
35     }
36     void clear(){
37         MEM(c,0);
38     }
39     void Update(int x,int d){
40         while(x <= N){
41             c[x] += d;
42             x += Lowbit(x);
43         }
44     }
45     int Getsum(int x){
46         int res = 0;
47         while(x){
48             res += c[x];
49             x -= Lowbit(x);
50         }
51         return res;
52     }
53 }bt;
54 
55 int Find(int x){
56     return fa[x] == x ? x : fa[x] = Find(fa[x]);
57 }
58 
59 int main(){
60     int a,b,c,k;
61     scanf("%d%d",&N,&M);
62     bt.Update(1,N);
63     REP(i,N) fa[i] = i,sz[i] = 1;
64     num = N;
65     REP(i,M){
66         scanf("%d",&c);
67         if(c == 0){
68             scanf("%d%d",&a,&b);
69             int x = Find(a);
70             int y = Find(b);
71             if(x == y) continue;
72             bt.Update(sz[x],-1);
73             bt.Update(sz[y],-1);
74             fa[x] = y;
75             sz[y] += sz[x];
76             bt.Update(sz[y],1);
77             num--;
78         }
79         else{
80             scanf("%d",&k);
81             k = num + 1 - k;
82             int l = 1,r = N;
83             while(l <= r){
84                 int mid = (l + r) / 2; //getmid(l,r);
85                 if(bt.Getsum(mid) >= k) r = mid - 1;
86                 else l = mid + 1;
87             }
88             printf("%d\n",l);
89         }
90     }
91     return 0;
92 }
View Code

相关文章:

  • 2021-06-29
  • 2021-07-28
  • 2022-01-09
  • 2021-06-15
  • 2022-02-28
  • 2021-10-15
  • 2021-10-26
  • 2021-05-16
猜你喜欢
  • 2021-12-31
  • 2022-12-23
  • 2021-08-30
  • 2021-12-09
  • 2021-07-03
  • 2022-12-23
  • 2022-01-22
相关资源
相似解决方案