题解 P1801 【黑匣子_NOI导刊2010提高(06)】

提供一种stl新的思路:vector

(当然这是treap,fhq treap的简化版,清清爽爽的短代码,让您远离平衡树和对顶堆)

可采用vector在线,每次边读入GET指令边输出

ADD(x):(插入值为x的数)

使用 insert()和lower_bound(),将某个值插入到它的下界

v.insert(lower_bound(v.begin(),v.end(),某个值),某个值);

GET(i):(输出当前vector里第i大的数)

直接输出v[i-1]因为vector是从0开始存的,v[i-1]即是vector的第i大

附上清爽崽代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;++i)
#define dwn(i,a,b) for(ll i=a;i>=b;--i) 

template <typename T> inline void rd(T &x){//读入优化
	x=0;char c=getchar();int f=0;
    while(!isdigit(c)){f|=c=='-';c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    x=f?-x:x;
} 

#define N 200010
int m,n;
int a[N];

vector<int>v;
int main(){
	rd(m),rd(n);
	rep(i,1,m)rd(a[i]);
	int l=1,r;
	rep(i,1,n){
		rd(r);
		rep(j,l,r) 
			v.insert(lower_bound(v.begin(),v.end(),a[j]),a[j]);
		l=r+1;
		printf("%d\n",v[i-1]);
	}
	return 0;
}

补充:vector也能A掉P3369 【模板】普通平衡树

解放生产力,偷懒是人类进步的阶梯

这里附上核心代码


vector<int>v;
int n,op,x;
int main(){
	rd(n);
	while(n--){
		rd(op),rd(x);
		if(op==1)v.insert(lower_bound(v.begin(),v.end(),x),x);
		if(op==2)v.erase(lower_bound(v.begin(),v.end(),x));
		if(op==3)printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
		if(op==4)printf("%d\n",v[x-1]);
		if(op==5)printf("%d\n",*--lower_bound(v.begin(),v.end(),x));
		if(op==6)printf("%d\n",*lower_bound(v.begin(),v.end(),x+1));
	}
	return 0;
}
/*操作:
1    插入x数
2    删除x数(若有多个相同的数,因只删除一个)
3    查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
4    查询排名为x的数
5    求x的前驱(前驱定义为小于x,且最大的数)
6    求x的后继(后继定义为大于x,且最小的数)
*/
/*

    定义:vector<int>a; 需<vector>头文件
    访问元素:a[x]  取出a中的第(x+1)个数(下标从0开始 O(1)
    a.begin():返回起始元素的迭代器 O(1)
    a.end():返回终止元素的迭代器 O(1)
    a.insert(a.begin()+pos,x):在第pos个数后面插入x O(n)
    a.erase(a.begin()+pos):删除pos位置的数 pos之后的数自动补齐 O(n)
    lower_bound(a.begin(),a.end(),x)返回第一个==x的位置的迭代器 O(logn)
    upper_bound(a.begin(),a.end(),x)返回最后一个==x的位置的后面一个的迭代器(x的后继 O(logn)
    *it:取出迭代器it中的值(大概只有我不知道
*/
posted @ 2019-10-08 12:26  设计涉及社稷  阅读(115)  评论(0编辑  收藏  举报