SGU 263. Towers
各种操作:
- put x c:表示在第 x 列上增加 c 个积木(c>0)。
- tput t x c:表示在塔 t 的第 x 列上增加 c 个积木(c>0)。
- towers:询问共有几座塔。
- cubes t:询问第 t 座塔共有几个积木。
- length t:询问第 t 座塔的长度。
- tcubes t x:询问第 t 座塔的第 x 列有几个积木。
对应做法:
- towers: 由于要查询tower的数目,以及删除一个tower,加入一个tower,考虑使用平衡树维护。
- put: 首先加积木这一件事情只会使得tower发生合并操作对吧,所以可以用并查集维护点属于那个tower。关于合并积木:先查找这个位置是否本来就有积木,如果有,加上就行拉,更新一下BST中的端点的cubes就行拉;否则加上之后插入BST内,如果其左边有towers,或者右边有towers,或者两边都有删除靠右边的节点,将信息传递到左边的节点,然后在并查集内把父亲指向左边节点的左端点,没拉。
- tput: 在某个tower内加积木,如果我知道某个tower的左端点,直接加就行了,之后更新BST内节点即可。
- cubes: 直接把大小放到tower的最左边的端点中,查询直接输出即可。
- lengths: 同上。
- tcubes: 同tput。
由于要求支持k大操作,set不适用,只好手写平衡树拉>_<!!。
notice:
- 删除节点旋转时要记录方向 int d = t->ch[]->fix < t->ch[]->fix; ,千万不要在这里图方便 else rot(t, t->ch[]->fix < t->ch[]->fix), del(t->ch[t->ch[]->fix < t->ch[]->fix], pos); ,因为已经把儿子转走了,如上定RE。
- 新建指针节点一定将其指向NULL,无论之后会不会给它赋值。
- 手残打错变量名。。。为什么每次敲数据结构题都会敲错变量名。。。
CODE:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + ;
const int maxp = 1e6; int n;
int fa[maxn], num[maxn]; int test_on; int find_fa(int x) {
if(fa[x] != x) fa[x] = find_fa(fa[x]);
return fa[x];
} class BST {
private:
struct treap_node {
treap_node *ch[];
int fix, size, pos, cubes, length;
treap_node() {
ch[] = ch[] = NULL;
}
treap_node(int _pos, int _cubes, int _lengh) {
pos = _pos, cubes = _cubes, length = _lengh;
ch[] = ch[] = NULL;
size = ;
fix = rand();
}
} *T;
void maintain(treap_node *x) {
if(x) {
x->size = ;
if(x->ch[]) x->size += x->ch[]->size;
if(x->ch[]) x->size += x->ch[]->size;
}
}
void rot(treap_node *&x, int d) {
treap_node *y = x->ch[d ^ ];
x->ch[d ^ ] = y->ch[d];
y->ch[d] = x;
maintain(x), maintain(y);
x = y;
}
void insert(treap_node *&t, int p, int c, int l) {
if(t == NULL) {
t = new treap_node(p, c, l);
} else {
if(p < t->pos) {
insert(t->ch[], p, c, l);
if(t->ch[]->fix < t->fix) rot(t, );
} else {
insert(t->ch[], p, c, l);
if(t->ch[]->fix < t->fix) rot(t, );
}
}
maintain(t);
}
void del(treap_node *&t, int pos) {
if(t->pos == pos) {
if(!(t->ch[]) || !(t->ch[])) {
treap_node *p = t;
if(t->ch[]) p = t->ch[];
else p = t->ch[];
t = NULL;
delete t;
t = p;
} else {
int d = t->ch[]->fix < t->ch[]->fix;
// notice
rot(t, d);
del(t->ch[d], pos);
}
} else del(t->ch[t->pos < pos], pos);
if(t) maintain(t);
}
treap_node *select(int k) {
treap_node *t = T;
int size;
while() {
size = t->ch[] ? t->ch[]->size : ;
if(k <= size) {
t = t->ch[];
} else if(k > size + ) {
k -= size + ;
t = t->ch[];
} else break;
}
return t;
}
treap_node *find(treap_node *t, int pos) {
if(t == NULL || t->pos == pos) return t;
return find(t->ch[t->pos < pos], pos);
} public: void print(treap_node *node) {
if(node == NULL) return ;
print(node->ch[]);
printf("address :%d size :%d fix :%d\n pos :%d cubes :%d length :%d\n", node, node->size, node->fix, node->pos, node->cubes, node->length);
printf(" ch[0] :%d ch[1] :%d\n", node->ch[], node->ch[]);
print(node->ch[]);
} int f, t, x, c;
treap_node *r;
void put() {
scanf("%d%d", &x, &c);
f = find_fa(x);
num[x] += c;
r = find(T, f);
if(r == NULL) {
insert(T, x, num[x], );
treap_node *p, *q;
p = q = NULL;
// notice
r = find(T, f);
if( < x - ) p = find(T, find_fa(x - ));
if(x + <= maxp) q = find(T, find_fa(x + ));
if(p != NULL || q != NULL) {
if(p != NULL) {
fa[r->pos] = p->pos;
p->cubes += r->cubes;
p->length += r->length;
del(T, r->pos);
r = p;
}
if(q != NULL) {
fa[q->pos] = r->pos;
r->cubes += q->cubes;
r->length += q->length;
// notice
del(T, q->pos);
}
}
} else {
r->cubes += c;
}
/*
r = select(1);
printf(" %d\n", r->length);
printf("%d\n", test_on);
print(T);
puts("");
*/
}
void tcubes() {
scanf("%d%d", &t, &x);
r = select(t);
printf("%d cubes in %dth column of %dth tower\n", num[r->pos + x - ], x, t);
}
void tput() {
scanf("%d%d%d", &t, &x, &c);
r = select(t);
num[r->pos + x - ] += c;
r->cubes += c;
}
void length() {
scanf("%d", &t);
r = select(t);
printf("length of %dth tower is %d\n", t, r->length);
}
void towers() {
printf("%d towers\n", T ? T->size : );
}
void cubes() {
scanf("%d", &t);
r = select(t);
printf("%d cubes in %dth tower\n", r->cubes, t);
}
} T; char ope[];
int main() {
#ifdef ONLINE_JUDGE
srand((int)time(NULL));
#endif for(int i = ; i < maxn; ++i) fa[i] = i;
scanf("%d", &n);
for(int i = ; i <= n; ++i) {
// test_on = i;
// printf("%d ", test_on);
scanf("%s", ope);
if(ope[] == 'p') {
T.put();
} else if(ope[] == 't' && ope[] == 'o') {
T.towers();
} else if(ope[] == 't' && ope[] == 'p') {
// puts("");
T.tput();
} else if(ope[] == 'c') {
T.cubes();
} else if(ope[] == 'l') {
T.length();
} else if(ope[] == 't' && ope[] == 'c') {
T.tcubes();
}
} return ;
}
SGU 263. Towers的更多相关文章
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :n个圆盘,m个柱子的汉诺塔输出步骤. ht ...
- SGU 202. The Towers of Hanoi Revisited
多柱汉诺塔问题. 引用自wiki百科 多塔汉诺塔问题 在有3个柱子时,所需步数的公式较简单,但对于4个以上柱子的汉诺塔尚未得到通用公式,但有一递归公式(未得到证明,但目前为止没有找到反例): 令为在有 ...
- LightOJ1126 Building Twin Towers(DP)
题目 Source http://www.lightoj.com/volume_showproblem.php?problem=1126 Description Professor Sofdor Al ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- UVA 10066 The Twin Towers
裸最长公共子序列 #include<time.h> #include <cstdio> #include <iostream> #include<algori ...
- ACM: SGU 101 Domino- 欧拉回路-并查集
sgu 101 - Domino Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Desc ...
- 【SGU】495. Kids and Prizes
http://acm.sgu.ru/problem.php?contest=0&problem=495 题意:N个箱子M个人,初始N个箱子都有一个礼物,M个人依次等概率取一个箱子,如果有礼物则 ...
- SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operati ...
- SGU 422 Fast Typing(概率DP)
题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...
随机推荐
- oracle数据库解锁
当我们修改数据库时用for update 或者使用rowId修改后,对表进行了锁定,由于某种原因没有对他进行关闭,我们需要关闭 select b.username,b.sid,b.serial#,lo ...
- Codeforces Round #514 (Div. 2) C. Sequence Transformation(递归)
C. Sequence Transformation 题目链接:https://codeforces.com/contest/1059/problem/C 题意: 现在有1~n共n个数,然后执行下面操 ...
- The Shortest Path in Nya Graph HDU - 4725
Problem Description This is a very easy problem, your task is just calculate el camino mas corto en ...
- C#学习之泛型准备
想要把泛型搞明白,最好先弄明白下面的代码实例 本实例是建立了两个类,然后在类中可以添加任意类型的值,并且可以利用foreach语句读出 //第一个节点类,放在一个文件中 using System; u ...
- [LeetCode] 7. Reverse Integer ☆
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have y ...
- Android之极光推送发送自定义消息
Android端实现主要代码: <span style="font-size:14px;">import java.io.IOException; import jav ...
- 数据结构:ST表
BZOJ1699 在经历了树套树和主席树的洗礼之后,所有的数据结构都显得格外地亲切,和自然.. ST算法能够实现O(nlogn)的预处理的情况下完成O(1)的区间最值查询 虽然这要求区间是静态的,也就 ...
- 【hdu1255】线段树求矩形面积交
题意大概就是上图这个样子.<=100组测试数据,每组<=1000个矩形. 题解: 这个问题怎么解决..做了上一题矩形面积并应该就会了.. 对于每个节点维护3个值: cnt:该节点所代表的这 ...
- 【BZOJ3339&&3585】mex [莫队][分块]
mex Time Limit: 20 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一个长度为n的数组{a1,a2,. ...
- Web Session 浅入浅出(山东数漫江湖)
使用过几种Web App开发语言和框架,都会接触到Session的概念.即使是一个简单站点访问计数的功能,也常常使用Session来实现的.其他常用的领域还有购物车,登录用户等.但是,对Session ...