hihocoder1711 评论框排版[并查集+set]

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <set>
 4 using namespace std;
 5 const int N = 1e5+5;
 6 
 7 struct Block {
 8     long long begin, all_size;    //root起始, root子树总大小
 9     long long dis, size, f;       //距离父节点起始距离, 自身大小, 父节点标号
10     bool operator <(const Block &rhs) const {
11         return begin < rhs.begin;
12     }
13 };
14 Block block[N];
15 
16 int findf(int x) {//找到标号x的根节点标号, 并让x直接连向根节点
17     if(x == block[x].f) return x;
18     int rt = findf(block[x].f);
19     int f = block[x].f;
20     block[x].dis += block[f].dis;
21     block[x].f = block[f].f;
22     return rt;
23 }
24 void merge(int x, int y) { //将标号y所在的子树merge到标号x所在的子树
25     int fx = findf(x), fy = findf(y);
26     if(fx == fy) return ;
27     block[fy].dis = block[fx].all_size;
28     block[fy].f = fx;
29     block[fx].all_size += block[fy].all_size;
30 }
31 
32 set<Block> se;
33 
34 int main() {
35     int n, k, h, x, tot = 0;
36     char op;
37     scanf("%d", &n);
38     for(int i = 1; i <= n; i++) {
39         scanf(" %c", &op);
40         if(op == 'I') {
41             scanf("%d%d", &k, &h);
42             int ID = ++tot;
43             block[tot] = {k, h, 0, h, tot};
44             if(se.empty()) {se.insert(block[ID]); continue ;}
45             
46             auto it = se.upper_bound(block[ID]);
47             if(it == se.begin()) {
48                 while(it != se.end() && block[ID].begin+block[ID].all_size >= it->begin) {
49                     int f = it->f;
50                     se.erase(it++);
51                     merge(ID, f);
52                 }
53                 se.insert(block[ID]);
54             }
55             else { // it != se.begin()
56                 auto tmp = it;
57                 --tmp;
58                 if(tmp->begin + tmp->all_size >= k) {
59                     int f = tmp->f;
60                     se.erase(tmp);
61                     merge(f, tot);
62                     ID = f;//////////////////////////////////////////
63                 }
64                 while(it != se.end() && block[ID].begin+block[ID].all_size >= it->begin) {
65                     int f = it->f;
66                     se.erase(it++);
67                     merge(ID, f);
68                 }
69                 se.insert(block[ID]);
70             }
71         }
72         else {
73             scanf("%d", &x);
74             int rt = findf(x);
75             long long L = block[x].dis+block[rt].begin;
76             long long R = L+block[x].size-1;
77             printf("%I64d %I64d\n", L, R);
78         }
79     }
80     return 0;  
81 }  
82 
83 /*
84 5  
85 I 1 5  
86 I 8 10  
87 I 5 5  
88 Q 3  
89 Q 2
90 */
View Code

 

posted @ 2018-06-06 19:40  我在地狱  阅读(205)  评论(0编辑  收藏  举报