求LCA练习+部分算法复习 2017.1.22
2017-01-22 21:57
495 查看
#include<iostream> #include<sstream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<cctype> #include<queue> #include<set> #include<map> #include<stack> #include<vector> #include<algorithm> #ifndef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; typedef bool boolean; #define smin(a, b) (a) = min((a), (b)) #define smax(a, b) (a) = max((a), (b)) template<typename T> inline void readInteger(T& u){ char x; int aFlag = 1; while(!isdigit((x = getchar())) && x != '-'); if(x == '-'){ aFlag = -1; x = getchar(); } for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0'); ungetc(x, stdin); u *= aFlag; } template<typename T> class ScapegoatTreeNode { public: T val; int count; int size; ScapegoatTreeNode* next[2]; ScapegoatTreeNode():count(1), size(1){ memset(next, 0, sizeof(next)); } ScapegoatTreeNode(T val):val(val), count(1), size(1){ memset(next, 0, sizeof(next)); } inline void maintain() { size = count; for(int i = 0; i < 2; i++) if(next[i] != NULL) size += next[i]->size; } inline void addCount(int c){ if(count == 0 && c < 0) return; size += c, count += c; } inline int cmp(T x){ if(val == x) return -1; return (x < val) ? (0) : (1); } }; template<typename T> class ScapegoatTree { protected: static void insert(ScapegoatTreeNode<T>*& node, T val){ if(node == NULL){ node = new ScapegoatTreeNode<T>(val); return; } int d = node->cmp(val); if(d == -1){ node->addCount(1); return; } insert(node->next[d], val); node->maintain(); } static boolean remove(ScapegoatTreeNode<T>*& node, T val){ if(node == NULL) return false; int d = node->cmp(val); if(d == -1){ node->addCount(-1); return true; } boolean res = remove(node->next[d], val); if(res) node->maintain(); return res; } static ScapegoatTreeNode<T>* findKth(ScapegoatTreeNode<T>*& node, int k){ int ls = (node->next[0] == NULL) ? (0) : (node->next[0]->size); if(k >= ls + 1 && k <= ls + node->count) return node; if(k <= ls) return findKth(node->next[0], k); return findKth(node->next[1], k - ls - node->count); } public: ScapegoatTreeNode<T>* root; vector<ScapegoatTreeNode<T>*> lis; ScapegoatTree():root(NULL){ } ScapegoatTreeNode<T>* rebuild(int l, int r){ if(l > r) return NULL; int mid = (l + r) >> 1; ScapegoatTreeNode<T>*& node = lis[mid]; node->next[0] = rebuild(l, mid - 1); node->next[1] = rebuild(mid + 1, r); node->maintain(); return node; } void rebuild(ScapegoatTreeNode<T>*& node, ScapegoatTreeNode<T>*& f){ lis.clear(); travel(node); int d = -1; if(f != NULL) d = f->cmp(node->val); ScapegoatTreeNode<T>* res = rebuild(0, lis.size() - 1); if(d != -1) f->next[d] = res; else root = res; } void insert(T val){ insert(root, val); } void remove(T val){ remove(root, val); } ScapegoatTreeNode<T>* findKth(int k){ return findKth(root, k); } }; int n; int lb, rb; ScapegoatTree<int> s; inline void init() { readInteger(lb); readInteger(rb); for(int i = lb; i <= rb; i++){ ScapegoatTreeNode<int>* node = new ScapegoatTreeNode<int>(i); readInteger(node->count); node->maintain(); s.lis.push_back(node); } s.root = s.rebuild(0, s.lis.size() - 1); } inline void solve() { readInteger(n); char cmd[10]; int a; while(n--) { scanf("%s", cmd); readInteger(a); if(cmd[0] == 'a'){ s.insert(a); }else if(cmd[0] == 'd'){ s.remove(a); }else{ ScapegoatTreeNode<int>* node = s.findKth(a); printf("%d\n", node->val); } } } int main(){ freopen("kth.in", "r", stdin); freopen("kth.out", "w", stdout); init(); solve(); return 0; }
替罪羊树
相关文章推荐
- 接口
- Kafka 0.10 安装及使用
- 永不明白的
- jdbctemplate
- Hadoop2.5.2学习04--HDFS原理及操作
- 百度语音的网页接口(待续)
- VB.NET读取版本信息
- spring中方法级验证参数
- 初探MeidaPlayer底层实现(二)
- TCP三次握手与四次挥手最简洁易懂的解释
- Python库安装
- vi命令使用
- Glide进阶详解(七)
- Spring 注释 Autowired 和@Resource 的区别
- Unity LineRender画线+计算空间距离+实时更新数据
- 零基础学编程
- java并发编程实践学习(1)线程安全
- hibernate常见错误
- MVC C# 页面跳转
- [置顶] ESP-TOUCH编码规则及解码