zoukankan      html  css  js  c++  java
  • BZOJ_1503 [NOI2004]郁闷的出纳员 【Splay树】

    一 题面

      [NOI2004]郁闷的出纳员

    二 分析

      模板题。

      对于全部员工的涨工资和跌工资,可以设一个变量存储起来,然后在进行删除时,利用伸展树能把结点旋转到根的特性,能够很方便的删除那些不符合值的点。同时,维护的结点数量信息也方便我们进行结果的统计。

    三 AC代码

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <fstream>
      6 using namespace std;
      7 
      8 const int MAXN = 1e5 + 15;
      9 class Splay
     10 {
     11 public:
     12     struct Node
     13     {
     14         Node *ch[2], *fa;
     15         int size, key;
     16         Node(){
     17             ch[0] = ch[1] = fa = NULL;
     18             key = size = 0;
     19         }
     20         void setc(Node *p, bool d){
     21             ch[d] = p;
     22             p->fa = this;
     23         }
     24         //判断是父节点的哪个孩子结点
     25         bool d(){
     26             //是父节点的有儿子
     27             return fa->ch[1] == this;
     28         }
     29         void push_up(){
     30             size = ch[0]->size + ch[1]->size + 1;
     31         }
     32     }*null, *root;
     33     Splay(){
     34         null = new Node;
     35         null->ch[0] = null->ch[1] = null->fa = null;
     36         root = null;
     37     }
     38     void rotate(Node *rt){
     39         Node* fa = rt->fa;
     40         bool d = rt->d();
     41         fa->fa->setc(rt, fa->d());
     42         fa->setc(rt->ch[!d], d);
     43         rt->setc(fa, !d);
     44         fa->push_up();
     45         if(root == fa)  root = rt;
     46     }
     47     Node* newNode(const int &key){
     48         Node* rt = new Node();
     49         rt->key = key;
     50         rt->size = 1;
     51         rt->ch[0] = rt->ch[1] = rt->fa = null;
     52         return rt;
     53     }
     54     void splay(Node* rt, Node* fa){
     55         while(rt->fa != fa){
     56             if(rt->fa->fa == fa)
     57                 rotate(rt);
     58             else{
     59                 //容易出错的位置
     60                 rt->d() == rt->fa->d() ? rotate(rt->fa) : rotate(rt);
     61                 rotate(rt);
     62             }
     63         }
     64         rt->push_up();
     65     }
     66     void insert(const int &key){
     67         if(root == null){
     68             root = newNode(key);
     69             return;
     70         }
     71         Node* t = root;
     72         while(t->ch[key > t->key] != null)
     73             t = t->ch[key > t->key];
     74         Node* c = newNode(key);
     75         t->setc(c, key > t->key);
     76         t->push_up();
     77         splay(c, null);
     78     }
     79     Node* get_kth(Node* rt, int k){
     80         Node* x = rt;
     81         if(x == null)
     82             return null;
     83         while(x->ch[0]->size + 1 != k){
     84             if(k < x->ch[0]->size + 1)
     85                 x = x->ch[0];
     86             else{
     87                 k -= x->ch[0]->size + 1;
     88                 x = x->ch[1];
     89             }
     90         }
     91         return x;
     92     }
     93 };
     94 
     95 int main()
     96 {
     97     //freopen("input.txt", "r", stdin);
     98     //freopen("out.txt", "w", stdout);
     99     int n, min, k;
    100     int data = 0, Cnt = 0;
    101     char c;
    102     Splay sptree;
    103     scanf("%d %d", &n, &min);
    104     while(n--){
    105         getchar();
    106         scanf("%c %d", &c, &k);
    107         if(c == 'I'){
    108             if(k < min)
    109                 continue;
    110             sptree.insert(k+data);
    111         }
    112         else if(c == 'A'){
    113             data -= k;
    114         }
    115         else if(c == 'S'){
    116             data += k;
    117             sptree.insert(min+data);
    118             Cnt += sptree.root->ch[0]->size;
    119             sptree.root=sptree.root->ch[1];
    120             sptree.root->fa = sptree.null;
    121         }
    122         else{
    123             if(k > sptree.root->size)
    124                 printf("-1
    ");
    125             else{
    126                 k = sptree.root->size - k + 1;
    127                 printf("%d
    ", sptree.get_kth(sptree.root, k)->key-data);
    128             }
    129         }
    130     }
    131     printf("%d
    ", Cnt);
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    10-10-12分页机制(xp)
    段间跳转之任务门
    段间跳转之TSS段
    mysql索引
    cat /proc/meminfo
    This system is not registered to Red Hat Subscription Management报错
    CentOS 6.5安装zabbix
    KVM(系统虚拟化模块)安装
    Linux时区更改
    学习ruby/rails, rvm是必不可少的工具之一
  • 原文地址:https://www.cnblogs.com/dybala21/p/10828907.html
Copyright © 2011-2022 走看看