现在的位置: 首页 > 综合 > 正文

Atomic Nucleus Investigation 线段树

2014年02月10日 ⁄ 综合 ⁄ 共 3653字 ⁄ 字号 评论关闭
题目描述

Recently the physicists have been investigating a large family of atomic nucleuses, named “X family”. They have discovered that these atomic nucleuses in X family are quite similar to each other, and can only be distinguished by their weights. And the smaller
the weight difference between two kinds of nucleuses is, the more possibly one kind tend to transform to the other.

To research X family in depth, the physicists have devised a series of experiments.

As the most important foundation of these experiments is to control the generation of X family nucleuses, and figure out the instant minimum weight difference among them, the physicists feel like devising a special device which can carry out different kinds
of instructions and accomplish the task above. Here are 3 kinds of instructions in desire:

-generate M

Suppose the weights of nucleuses are numbers starting from 1, andM is a positive integer, then the device should produce a nucleus weighted M. If there already exists a nucleus with the same weight, then this instruction
should not be taken into account.

-
remove M

Suppose M is a positive integer, then the device should remove the existing nucleus weightedM. If no such nucleus exists, the instruction should also be ignored. Please note that a nucleus can exist all the same
unless it’s removed by the device.

-
query

The device should output the instant minimum weight difference among those existing nucleuses. For example, if there exists 3 nucleuses weighted 1, 7, 10 respectively, then the minimum weight difference is 10-7=3. If there is less
than 2 nucleuses with different weight, the query result should be “-1” (without quotes).

Now, your task is to write a program to simulate this special device.

输入格式

Input may contain multiple test cases. The first line is a positive integert, the number of test cases below. For each test case, the input is an instruction sequence. The first line is a single integern, (1 ≤
n ≤ 100000), denoting the number of instructions in this case. And n instructions follow. Each of them is one of the three kinds of instruction as described above, where M is a positive integer no more than 100000.

输出格式

For each test case, each query instruction should correspond to one line of output, containing only one positive integer, which is the corresponding query result. Please output a blank line between test cases.

http://soj.me/show_problem.php?pid=1802

 

 

最经典的线段树题目,建立一个数轴上的线段树,然后维护这个一维数集。

// Problem#: 1802
// Submission#: 1192789
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 131072;
const int INF = 1000000;

struct Node{
    int min;
    int max;
    int min_diff;
    }node[N << 1];

void init(){
    int num = N << 1;
    for (int i =1;i < num;++i){
        node[i].min = INF;
        node[i].max = -INF;
        node[i].min_diff = INF;
        }
    }

inline int query(){
    return node[1].min_diff < N ? node[1].min_diff:-1;
    }
inline int get_left_child(int p){
    return p << 1;
    }
inline int get_right_child(int p){
    return (p << 1)+1;
    }
inline int get_parent(int c){
    return c >> 1;
    }
inline int get_node(int v){
    return v+N-1;
    }
void update(int m){
    int left_child = get_left_child(m),right_child = get_right_child(m);
    node[m].min = min(node[left_child].min,node[right_child].min);
    node[m].max = max(node[left_child].max,node[right_child].max);
    node[m].min_diff = min(node[left_child].min_diff,node[right_child].min_diff);
    node[m].min_diff = min(node[m].min_diff,node[right_child].min-node[left_child].max);
    }

void add(int v){
    int m = get_node(v);
    if ( node[m].min == INF){
        node[m].min = v;
        node[m].max = v;
        do {
            m = get_parent(m);
            update(m);
            } while(m>1);
        }
    }

void remove(int v){
    int m = get_node(v);
    if ( node[m].min == v){
        node[m].min = INF;
        node[m].max = -INF;
        do {
            m = get_parent(m);
            update(m);
            } while(m>1);
        }
    }

int main(){
    int casen;
    scanf("%d",&casen);
    while(--casen>=0){
        init();
        int n;
        scanf("%d",&n);
        for(int i=0; i<n; ++i){
            char cmd[10];
            scanf("%s",cmd);
            if(cmd[0] == 'q'){
                printf("%d\n",query());
                } else {
                    int v;
                    scanf("%d",&v);
                    if(cmd[0] == 'g')
                        add(v);
                    else
                        remove(v);
                }
            }
        if (casen > 0)
            printf("\n");
        }
    return 0;
    }                                 

 

抱歉!评论已关闭.