zoukankan      html  css  js  c++  java
  • [洛谷][P1503][鬼子进村][Treap]

    原题地址


    题意就不解释了吧。

    看到这道题,一开始YY把所有点加进treap里面,然后完全跟着操作走,应该是可做的。[在treap里面找连续的一段应该很简单,只要有一定代码能力都行|||||||吧。。。。]

    可不幸的因为本人太弱,不想写,就不得不YY其它的做法,我们可以发现,被困士兵能通过的房子组成的序列的两个端点为被毁灭的两个房屋。[左端点有可能为零,即最左端,右端点可能为n+1,即最右端] 所以我们每次把被删除的端点加入treap,对于查询,我们查当前士兵的前驱和后继即可


    上代码 :

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<string>
    #include<cmath>
    #include<cctype>
    
    const int N = 5e4 + 7,INF = 0x7fffffff;
    
    #define R121() ((rand()<<12)+(rand()<<7)+rand())
    #include<bitset>
    #define R233() (R121() % 456454541 + R121() % 452112101 + R121() % 121231 + 1)
    using std :: bitset;
    
    int n,m,v;
    
    class Treap {
    private :
    	struct Node {
    		Node *son[2];
    		int size,data,hr;
    		Node () {}
    		Node (int data,Node *fl) : data(data) { son[0] = son[1] = fl; size = 1; hr = R233(); }
    		void update () { size = son[0] -> size + son[1] -> size + 1;}
    	}*Null,*root,*pool,meme[N];
    	
    	int ball;
    	
    	void rotate (Node *&T,bool v) {
    		Node *Tt = T -> son[v];
    		T -> son[v] = Tt -> son[v^1];
    		Tt -> son[v^1] = T;
    		T -> update(); Tt -> update();
    		T = Tt;
    	}
    	
    	void Insert (Node *&T) {
    		if(T == Null) { T = new (pool++) Node (ball,Null); return ; }
    		bool v = T -> data < ball;
    		Insert (T -> son[v]);
    		if(T -> son[v] -> hr < T -> hr) rotate (T , v);
    		else T -> update();
    	}
    	
    	void Delete (Node *&T) {
    		if(T == Null) return;
    		if(T -> data == ball) {
    			if(T -> son[0] == Null || T -> son[1] == Null) {
    				bool v = T -> son[1] != Null;
    				T = T -> son[v];
    				return ;
    			}
    			bool v = T -> son[0] -> hr > T -> son[1] -> hr;
    			rotate (T , v);
    			Delete (T -> son[v^1]);
    		} else {
    			bool v = ball > T -> data;
    			Delete (T -> son[v]);
    		}
    		T -> update();
    	}
    	
    	int Subsequent (Node *&T) {
    		if(T == Null) return n+1;
    		if(T -> data <= ball) return Subsequent (T -> son[1]);
    //		if(T -> data + 1 <= ball) return T -> data;
    //		if(T -> data < ball) 
    		int k = Subsequent (T -> son[0]);
    		return k == n + 1 ? T -> data : k;
    	}
    	int Precursor (Node *&T) {
    		if(T == Null) return 0;
    		if(T -> data >= ball) return Precursor (T -> son[0]);
    		int k = Precursor (T -> son[1]);
    		return k == 0 ? T -> data : k;
    	}
    	
    	
    public :
    	Treap () { Null = new Node(); Null -> size = 0; }
    	void clear () { pool = meme; root = Null; }
    	void Ins (int xxx) { ball = xxx; Insert(root); }
    	void Del (int xxx) { ball = xxx; Delete(root); }
    	int Sub (int xxx) { ball = xxx; return Subsequent(root); }
    	int Pre (int xxx) { ball = xxx; return Precursor(root); }
    }treap;
    
    char opt[N];
    bitset<N>vis;
    int stk[N],top;
    
    int main () {
    	scanf("%d%d",&n,&m); treap.clear();
    	for(int i=1;i<=m;++i) {
    		scanf("%s",opt);
    		if(opt[0] == 'R') treap.Del(stk[top--]),vis.flip(stk[top+1]);
    		else {
    			scanf("%d",&v);
    			if(opt[0] == 'D') { if(!vis.test(v)) treap.Ins(v),vis.flip(v),stk[++top]=v; }
    			else if(opt[0] == 'Q') {
    				if(vis.test(v)) puts("0");
    				else printf("%d
    ",	treap.Sub(v) - treap.Pre(v) - 1);
    			}
    		}
    	}
    	return 0;	
    }

    That is all. Thank you for watching!

  • 相关阅读:
    css3实现轮播2
    css3实现轮播1
    读阮一峰ES6笔记4:字符串的新增方法
    读阮一峰ES6笔记3:字符串的扩展
    应用流策略与检查配置结果
    配置流策略
    配置流行为
    配置流分类
    "流量监管"和"流量整形"的区别
    802.1p 优先级与内部优先级的映射关系
  • 原文地址:https://www.cnblogs.com/dcoi-king/p/5353660.html
Copyright © 2011-2022 走看看