【POJ 1442 && 洛谷 P1801】黑匣子(替罪羊树做法)
来源:互联网 发布:mac os10.6.8镜像下载 编辑:程序博客网 时间:2024/05/17 12:48
Black Box
Time Limit: 1000MSMemory Limit: 10000KTotal Submissions: 13823Accepted: 5626
Description
Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are two types of transactions:
ADD (x): put element x into Black Box;
GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box. Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non- descending.
Let us examine a possible sequence of 11 transactions:
Example 1
It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type.
Let us describe the sequence of transactions by two integer arrays:
1. A(1), A(2), …, A(M): a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, M <= 30000. For the Example we have A=(3, 1, -4, 2, 8, -1000, 2).
2. u(1), u(2), …, u(N): a sequence setting a number of elements which are being included into Black Box at the moment of first, second, … and N-transaction GET. For the Example we have u=(1, 2, 6, 6).
The Black Box algorithm supposes that natural number sequence u(1), u(2), …, u(N) is sorted in non-descending order, N <= M and for each p (1 <= p <= N) an inequality p <= u(p) <= M is valid. It follows from the fact that for the p-element of our u sequence we perform a GET transaction giving p-minimum number from our A(1), A(2), …, A(u(p)) sequence.
ADD (x): put element x into Black Box;
GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box. Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non- descending.
Let us examine a possible sequence of 11 transactions:
Example 1
N Transaction i Black Box contents after transaction Answer
(elements are arranged by non-descending)
1 ADD(3) 0 3
2 GET 1 3 3
3 ADD(1) 1 1, 3
4 GET 2 1, 3 3
5 ADD(-4) 2 -4, 1, 3
6 ADD(2) 2 -4, 1, 2, 3
7 ADD(8) 2 -4, 1, 2, 3, 8
8 ADD(-1000) 2 -1000, -4, 1, 2, 3, 8
9 GET 3 -1000, -4, 1, 2, 3, 8 1
10 GET 4 -1000, -4, 1, 2, 3, 8 2
11 ADD(2) 4 -1000, -4, 1, 2, 2, 3, 8
It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type.
Let us describe the sequence of transactions by two integer arrays:
1. A(1), A(2), …, A(M): a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, M <= 30000. For the Example we have A=(3, 1, -4, 2, 8, -1000, 2).
2. u(1), u(2), …, u(N): a sequence setting a number of elements which are being included into Black Box at the moment of first, second, … and N-transaction GET. For the Example we have u=(1, 2, 6, 6).
The Black Box algorithm supposes that natural number sequence u(1), u(2), …, u(N) is sorted in non-descending order, N <= M and for each p (1 <= p <= N) an inequality p <= u(p) <= M is valid. It follows from the fact that for the p-element of our u sequence we perform a GET transaction giving p-minimum number from our A(1), A(2), …, A(u(p)) sequence.
Input
Input contains (in given order): M, N, A(1), A(2), …, A(M), u(1), u(2), …, u(N). All numbers are divided by spaces and (or) carriage return characters.
Output
Write to the output Black Box answers sequence for a given sequence of transactions, one number each line.
Sample Input
7 4
3 1 -4 2 8 -1000 2
1 2 6 6
Sample Output
3
3
1
2
Source
Northeastern Europe 1996
题意
有一些ADD和GET操作。n次ADD操作,每次往序列中加入一个数,由ADD操作可知序列长度为1-n时序列的组成。GET操作输入一个序列长度,第i个数
ai 表示你需要输出当前长度序列为ai (即在第ai 次ADD操作后)第i大的元素的值。给出的GET操作输入非降。
思路
虽然这题好像一眼望上去就是splay,或者一些STL的奇技淫巧过这题,但我太菜了并不会splay这个东西,所以我就用上了不久前刚学到的替罪羊树,没想到还跑得挺快,在POJ上只用了94ms,因为这只是一道模板题,所以……好像也没什么好讲的..只是我刚开始记录下查询操作的时候用的是map里套vector来表示在这个ADD操作后是否有查询值,结果T掉了..然后我发现GET操作输入的序列是非降的。。于是只要在操作的时候记录上次已经查询完的位置在哪然后直接在那里往下找就行了。
Code
#pragma GCC optimize(3)#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<cctype>#include<climits>#include<cstdlib>#include<cmath>#include<map>#include<stack>#include<climits>#include<vector>using namespace std;typedef long long ll;bool Finish_read;template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}/*================Header Template==============*/struct ScapeGoatTree { static const int maxn=200010,oo=(1LL<<31)-1; static const double alpha=0.75; int cntx,root; struct TreeNode { int son[2]; int fa; int siz; int num; }t[maxn]; int treeid[maxn],cnt; inline bool balance(int id) { return (double)t[id].siz*alpha>=(double)t[t[id].son[0]].siz&&(double)t[id].siz*alpha>=(double)t[t[id].son[1]].siz; } inline void recycle(int id) { if(t[id].son[0]) recycle(t[id].son[0]); treeid[++cnt]=id; if(t[id].son[1]) recycle(t[id].son[1]); } inline int build(int l,int r) { if(l>r) return 0; int mid=(l+r)>>1,id=treeid[mid]; t[t[id].son[0]=build(l,mid-1)].fa=id; t[t[id].son[1]=build(mid+1,r)].fa=id; t[id].siz=t[t[id].son[0]].siz+t[t[id].son[1]].siz+1; return id; } inline void rebuild(int id) { cnt=0; recycle(id); int fa=t[id].fa,child=t[t[id].fa].son[1]==id,current=build(1,cnt); t[t[fa].son[child]=current].fa=fa; if(id==root) root=current; } inline void insert(int x) { int now=root,current=++cntx; t[current].siz=1;t[current].num=x; while(1) { t[now].siz++; bool child=x>=t[now].num; if(t[now].son[child]) now=t[now].son[child]; else { t[t[now].son[child]=current].fa=now; break; } } int need=0; for(int i=current;i;i=t[i].fa) if(!balance(i)) need=i; if(need) rebuild(need); } inline int get_kth(int x) { int now=root; while(1) { if(t[t[now].son[0]].siz==x-1) return now; else if(t[t[now].son[0]].siz>=x) now=t[now].son[0]; else { x-=t[t[now].son[0]].siz+1; now=t[now].son[1]; } } return now; } inline void init() { cntx=2;root=1; t[1].num=-oo,t[1].siz=2,t[1].son[1]=2; t[2].num=oo,t[2].siz=1,t[2].fa=1; } int n,q,val[300001],pos,o[300001]; inline void main() { init(); read(n);read(q); for(int i=1;i<=n;i++) read(val[i]); for(int i=1;i<=q;i++) read(o[i]); int pos=1; for(int i=1;i<=n;i++) { insert(val[i]); while(o[pos]==i) writeln(t[get_kth(pos+1)].num),pos++; } }}SGT;int main() { SGT.main(); return 0;}
阅读全文
1 0
- 【POJ 1442 && 洛谷 P1801】黑匣子(替罪羊树做法)
- 洛谷P1801 黑匣子(堆 )
- [codevs2573/洛谷P1801]黑匣子
- 洛谷P1801 黑匣子
- 洛谷 [P1801] 黑匣子
- 洛谷 P1801 黑匣子_NOI导刊2010提高(06)
- 洛谷 P1801 黑匣子_NOI导刊2010提高(06)
- 洛谷 P1801 黑匣子_NOI导刊2010提高(06)
- 洛谷 P1801 黑匣子_NOI导刊2010提高(06)
- 黑匣子_NOI导刊2010提高(06) 洛谷p1801
- 洛谷P1801 黑匣子_NOI导刊2010提高(06)
- 洛谷P1801 黑匣子_NOI导刊2010提高(06)
- [P1801]黑匣子
- P1801 黑匣子(对顶堆)
- 洛谷 P1801 [NOI导刊2010提高(06)] 黑匣子
- 替罪羊树模板(BZOJ3224)
- Template_Scapegoat_Tree(替罪羊树模板)
- 替罪羊树
- C 语言简介
- jQuery中的ajax
- POJ 1562Oil Deposits深搜
- 连接mysql报错Property ‘driverClassName’ threw exception :could not load jdbc driver
- 用循环制作乘法口诀表
- 【POJ 1442 && 洛谷 P1801】黑匣子(替罪羊树做法)
- 7-6 红色警报(25 分)(并查集)
- 数据库_索引总结
- Redis初识
- JAVA核心技术卷2 第四章Socket
- 冒泡排序、快速排序
- LeetCode-028 Implement strStr()
- [NTT][斯特林数]BZOJ 5093: 图的价值
- 哈尔滨理工大学第七届程序设计竞赛决赛(网络赛-高年级组)A 所有情况的和