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 */
诸神对凡人心生艳羡,厌倦天堂。