zoukankan      html  css  js  c++  java
  • POJ 2352 Stars Treap & 线段树

    其实这里就是用Treap来实现了一个求和的过程,其实这种区间操作还是用线段树或者是Splay比较方便。

    将点排序之后随便搞一下就就好,要注意的就是有点重复情况,我这里是把树的每一个节点又添加了一个cnt域来维护的,自己手撸的平衡树就是这么灵活= =

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    
    struct Node {
    	Node *ch[2];
    	int rkey, size, val, cnt;
    	Node(int val) : val(val) {
    		ch[0] = ch[1] = NULL;
    		rkey = rand();
    		size = cnt = 1;
    	}
    	void maintain() {
    		size = cnt;
    		if (ch[0] != NULL) size += ch[0]->size;
    		if (ch[1] != NULL) size += ch[1]->size;
    	}
    };
    
    struct Treap {
    
    	Node *root;
    
    	Treap() {
    		root = NULL;
    	}
    
    	void rotate(Node *&o, int d) {
    		Node *k = o->ch[d ^ 1];
    		o->ch[d ^ 1] = k->ch[d];
    		k->ch[d] = o;
    		k->maintain(); o->maintain();
    		o = k;
    	}
    
    	void remove_tree(Node *&o) {
    		if (o == NULL) return;
    		if (o->ch[0] != NULL) remove_tree(o->ch[0]);
    		if (o->ch[1] != NULL) remove_tree(o->ch[1]);
    		delete o;
    		o = NULL;
    	}
    
    	void insert(Node *&o, int x) {
    		if (o == NULL) o = new Node(x);
    		else if (o->val == x) o->cnt++;
    		else {
    			int d = x > o->val;
    			insert(o->ch[d], x);
    			if (o->ch[d]->rkey > o->rkey) rotate(o, d ^ 1);
    		}
    		o->maintain();
    	}
    
    	int getsize(Node *o) {
    		if (o == NULL) return 0;
    		return o->size;
    	}
    
    	int query(Node *o, int x) {
    		if (o == NULL) return 0;
    		if (o->val == x) {
    			return getsize(o->ch[0]) + o->cnt - 1;
    		}
    		if (x > o->val) return getsize(o->ch[0]) + o->cnt + query(o->ch[1], x);
    		else return query(o->ch[0], x);
    	}
    
    	void clear() {
    		remove_tree(root);
    	}
    
    	void insert(int x) {
    		insert(root, x);
    	}
    
    	int query(int x) {
    		return query(root, x);
    	}
    };
    
    const int maxn = 2e4 + 10;
    
    struct Point {
    	int x, y;
    	Point(int x = 0, int y = 0) : x(x), y(y) {}
    	bool operator < (const Point &p) const {
    		if (y == p.y) return x < p.x;
    		return y < p.y;
    	}
    };
    
    int levcnt[maxn], n;
    Point p[maxn];
    Treap tree;
    
    int main() {
    	while (scanf("%d", &n) != EOF) {
    		for (int i = 1; i <= n; i++) {
    			int x, y; scanf("%d%d", &x, &y);
    			p[i] = Point(x, y);
    		}
    		sort(p + 1, p + 1 + n);
    		memset(levcnt, 0, sizeof(levcnt));
    		tree.clear();
    		for (int i = 1; i <= n; i++) {
    			tree.insert(p[i].x);
    			int ret = tree.query(p[i].x);
    			levcnt[ret]++;
    		}
    		for (int i = 0; i < n; i++) {
    			printf("%d
    ", levcnt[i]);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    浅谈React工作原理
    手撕ES6--Promise
    快速安装create-react-app脚手架
    使用render函数渲染组件
    视图的创建与使用 Sql Server View
    数据库 简单查询 Sql Server 学生表 课程表 选课表
    基于WebServices简易网络聊天工具的设计与实现
    基于Web的实验室管理系统技术简要报告
    基于 控制台 简易 学生信息管理系统 (增、删、改)
    .net序列化与反序列化——提供多次存储对象集后读取不完全解决方案
  • 原文地址:https://www.cnblogs.com/rolight/p/4276669.html
Copyright © 2011-2022 走看看