SPOJ ORDERSET - Order statistic set
ORDERSET - Order statistic set
In this problem, you have to maintain a dynamic set of numbers which support the two fundamental operations
- INSERT(S,x): if x is not in S, insert x into S
- DELETE(S,x): if x is in S, delete x from S
and the two type of queries
- K-TH(S) : return the k-th smallest element of S
- COUNT(S,x): return the number of elements of S smaller than x
Input
- Line 1: Q (1 ≤ Q ≤ 200000), the number of operations
- In the next Q lines, the first token of each line is a character I, D, K or C meaning that the corresponding operation is INSERT, DELETE, K-TH or COUNT, respectively, following by a whitespace and an integer which is the parameter for that operation.
If the parameter is a value x, it is guaranteed that 0 ≤ |x| ≤ 109. If the parameter is an index k, it is guaranteed that 1 ≤ k ≤ 109.
Output
For each query, print the corresponding result in a single line. In particular, for the queries K-TH, if k is larger than the number of elements in S, print the word 'invalid'.
Example
Input
8
I -1
I -1
I 2
C 0
K 2
D -1
K 1
K 2 Output
1
2
2
invalid
分析
可以用Treap做,也可以Splay什么的,先用权值线段树水一水,再用Treap水一水。
代码
权值线段树
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> using namespace std; #define N 200005 struct node
{
int lt, rt, cnt;
}tree[N << ]; void build(int p, int l, int r)
{
node &t = tree[p]; t.lt = l;
t.rt = r;
t.cnt = ; if (l == r)
return; int mid = (l + r) >> ; build(p << , l, mid);
build(p << | , mid + , r);
} void insert(int p, int pos, int val)
{
node &t = tree[p]; t.cnt += val; if (t.lt == t.rt)
return; int mid = (t.lt + t.rt) >> ; if (pos <= mid)
insert(p << , pos, val);
else
insert(p << | , pos, val);
} int query(int p, int l, int r)
{
if (l > r)return ; node &t = tree[p]; if (t.lt == l && t.rt == r)
return t.cnt; int mid = (t.lt + t.rt) >> ; if (r <= mid)
return query(p << , l, r);
if (l > mid)
return query(p << | , l, r);
return query(p << , l, mid) + query(p << | , mid + , r);
} int rnk(int p, int rk)
{
node &t = tree[p]; if (t.lt == t.rt)
return t.lt; if (tree[p << ].cnt >= rk)
return rnk(p << , rk); else
return rnk(p << | , rk - tree[p << ].cnt);
} int n;
int a[N];
int b[N]; char s[N][]; signed main(void)
{
scanf("%d", &n); for (int i = ; i <= n; ++i)
scanf("%s%d", s[i], &a[i]); memcpy(b, a, sizeof(b)); sort(b + , b + + n); int m = unique(b + , b + + n) - b; build(, , m); for (int i = ; i <= n; ++i)if (s[i][] != 'K')
a[i] = lower_bound(b + , b + m, a[i]) - b; for (int i = ; i <= n; ++i)
{
char &c = s[i][]; if (c == 'I')
{
if (!query(, a[i], a[i]))
insert(, a[i], );
}
else if (c == 'D')
{
if (query(, a[i], a[i]))
insert(, a[i], -);
}
else if (c == 'K')
{
if (query(, , m) >= a[i])
printf("%d\n", b[rnk(, a[i])]);
else printf("invalid\n");
}
else if (c == 'C')
{
printf("%d\n", query(, , a[i] - ));
}
}
}
SegTree.cpp
Treap
#include <bits/stdc++.h> class treap
{
private: struct node
{
int key;
int tag;
int siz;
node *lson;
node *rson;
node(int k = , int t = rand()) :
key(k), tag(t), siz(), lson(), rson() {};
}; int getSize(node *&t)
{
if (t == NULL)return ;
t->siz = ;
if (t->lson)
t->siz += t->lson->siz;
if (t->rson)
t->siz += t->rson->siz;
return t->siz;
} void rotateLeft(node *&t)
{
node *r = t->rson;
t->rson = r->lson;
r->lson = t;
getSize(t);
getSize(r);
t = r;
} void rotateRight(node *&t)
{
node *l = t->lson;
t->lson = l->rson;
l->rson = t;
getSize(t);
getSize(l);
t = l;
} void insertNode(node *&t, int k)
{
if (t == NULL)
t = new node(k);
else
{
if (k < t->key)
{
insertNode(t->lson, k);
if (t->lson->tag > t->tag)
rotateRight(t);
}
else if (k > t->key)
{
insertNode(t->rson, k);
if (t->rson->tag > t->tag)
rotateLeft(t);
}
}
getSize(t);
} void deleteNode(node *&t)
{
if (t->lson == NULL)
t = t->rson;
else if (t->rson == NULL)
t = t->lson;
else
{
if (t->lson->tag > t->rson->tag)
rotateRight(t), deleteNode(t->rson);
else
rotateLeft(t), deleteNode(t->lson);
}
getSize(t);
} void deleteNode(node *&t, int k)
{
if (t != NULL)
{
if (k == t->key)
deleteNode(t);
else if (k < t->key)
deleteNode(t->lson, k);
else
deleteNode(t->rson, k);
getSize(t);
}
} node *findElement(node *&t, int k)
{
if (k == t->key)
return t;
else if (k < t->key)
return findElement(t->lson, k);
else
return findElement(t->rson, k);
} node *kthElement(node *&t, int k)
{
int leftSize = getSize(t->lson);
if (k == leftSize + )
return t;
else if (k <= leftSize)
return kthElement(t->lson, k);
else
return kthElement(t->rson, k - leftSize - );
} int countSmaller(node *&t, int k)
{
if (t == NULL)return ;
if (k == t->key)
return getSize(t->lson);
else if (k < t->key)
return countSmaller(t->lson, k);
else
return countSmaller(t->rson, k) + getSize(t->lson) + ;
} int countBigger(node *&t, int k)
{
if (t == NULL)return ;
if (k == t->key)
return getSize(t->rson);
else if (k > t->key)
return countBigger(t->rson, k);
else
return countBigger(t->lson, k) + getSize(t->rson) + ;
} node *treapRoot; public: treap(void)
{
treapRoot = NULL;
srand(time() + );
} int size(void)
{
return getSize(treapRoot);
} void insert(int key)
{
insertNode(treapRoot, key);
} void erase(int key)
{
deleteNode(treapRoot, key);
} int kthElement(int key)
{
return kthElement(treapRoot, key)->key;
} int countSmaller(int key)
{
return countSmaller(treapRoot, key);
} }t; signed main(void)
{
using namespace std; int n; scanf("%d", &n); char s[]; int num; while (n--)
{
scanf("%s%d", s, &num); char c = s[]; if (c == 'I')
t.insert(num);
else if (c == 'D')
t.erase(num);
else if (c == 'C')
printf("%d\n", t.countSmaller(num));
else
{
if (num <= t.size())
printf("%d\n", t.kthElement(num));
else
puts("invalid");
}
}
}
Treap.cpp
@Author: YouSiki
SPOJ ORDERSET - Order statistic set的更多相关文章
- SPOJ 3273 - Order statistic set , Treap
点击打开链接 题意: 集合S支持一下四种操作: INSERT(S,x) : 假设S中没有x,则插入x DELETE(S,x): 假设S中有x,则删除x K-TH(S): ...
- Order Statistic
目录 The Order Statistic 引理1 的一些基本性质 顺序统计量的分布 顺序统计量的条件分布 特殊分布的特殊性质 Order Statistic The Order Statistic ...
- (转)約瑟夫問題的兩個O(log n)解法
約瑟夫問題的兩個O(log n)解法 這個是學習編程時的一個耳熟能詳的問題了: n個人(編號爲0,1,...,n-1)圍成一個圈子,從0號開始依次報數,每數到第m個人,這個人就得自殺, 之後從下個人開 ...
- extSourceStat_7Day_Orders.php
<?php /** Log文件格式2012/7/4 列号 字段含义 取值 ------------------------------------------------------------ ...
- Heapsort 堆排序算法详解(Java实现)
Heapsort (堆排序)是最经典的排序算法之一,在google或者百度中搜一下可以搜到很多非常详细的解析.同样好的排序算法还有quicksort(快速排序)和merge sort(归并排序),选择 ...
- 【转】ActiveMQ与虚拟通道
郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436 ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个 ...
- SSE图像算法优化系列二十三: 基于value-and-criterion structure 系列滤波器(如Kuwahara,MLV,MCV滤波器)的优化。
基于value-and-criterion structure方式的实现的滤波器在原理上其实比较简单,感觉下面论文中得一段话已经描述的比较清晰了,直接贴英文吧,感觉翻译过来反而失去了原始的韵味了. T ...
- CF-1055E:Segments on the Line (二分&背包&DP优化)(nice problem)
You are a given a list of integers a 1 ,a 2 ,…,a n a1,a2,…,an and s s of its segments [l j ;r j ] [ ...
- 算法导论-顺序统计-快速求第i小的元素
目录 1.问题的引出-求第i个顺序统计量 2.方法一:以期望线性时间做选择 3.方法二(改进):最坏情况线性时间的选择 4.完整测试代码(c++) 5.参考资料 内容 1.问题的引出-求第i个顺序统计 ...
随机推荐
- PAT 1005. 继续(3n+1)猜想 (25) JAVA
当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对n=3进行验证的时候,我们需要计算3.5.8.4.2.1,则当我们对n=5.8.4.2进行验证的时候,就可以直接 ...
- Openjudge 1.12-04
04:最匹配的矩阵 查看 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个m*n的矩阵A和r*s的矩阵B,其中0 < r ≤ m, 0 < s ≤ n,A.B所有 ...
- Web服务器之iis,apache,tomcat三者之间的比较
IIS-Apache-Tomcat的区别 IIS与Tomcat的区别 IIS是微软公司的Web服务器.主要支持ASP语言环境. Tomcat是Java Servlet 2.2和JavaServer P ...
- ssh 免密码设置失败原因总结
先复习一下设置ssh免密码操作的步骤: 进入主目录 cd 生成公钥 ssh-keygen -t rsa -P '' (注:最后是二个单引号,表示不设置密码) 然后分发公钥到目标机器 ssh-copy- ...
- Java的性能优化
http://www.toutiao.com/i6368345864624144897/?tt_from=mobile_qq&utm_campaign=client_share&app ...
- java 实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。
package xidian.sl.netcredit.util; /** * Copyright (C) 2009-2010 Yichuan, Fuchun All rights reserved. ...
- centos7.2安装phpmyadmin
首先服务器要有web 环境 yum install phpmyadmin 修改/etc/http.conf/conf.d/phpMyadmin.conf 将 #Require ip 127.0.0. ...
- ElasticSearch入门系列(二)交互API
一.基于HTTP协议,以JSON为数据交互格式的RESTful API 向ElasticSearch发出请求的组成部分与其他的普通的HTTP请求是一样的: curl -X<VERB> '& ...
- Android 强制竖屏
一般android 显示内容都有两种实现方式,java代码中实现,xml布局中实现(或者权限管理页面) 直接上代码: java方法 setRequestedOrientation(ActivityIn ...
- redis的redis.conf文件详解
常用的: GENERAL: daemonize yes 守护进程 port 6379 指定Redis监听端口 requirepass 1 设置认证密码为1 REPLICATION: slave ...