SOJ1802 Atomic Nucleus Investigation
来源:互联网 发布:stp 查看环路端口 编辑:程序博客网 时间:2024/05/29 17:14
http://www.soj.me/show_problem.php?pid=1802
题意:维护一个整数的集合,有以下操作:
1.插入一个数,若已存在则不操作。
2.删除一个数,若不存在则不操作。
3.输出当前集合中两数差的最小值。
简单线段树
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;#define N 131072#define M 1000000int n1,n;struct point{ int max; int min; int dis;}p[2*N-1];void init(){ int i,j; for (i=0;i<=2*N-1;i++) { p[i].max=-M; p[i].min=M; p[i].dis=M; }}int getparent(int m){ return m/2;}int getlchild(int m){ return m*2;}int getrchild(int m){ return m*2+1;}void update(int m)//线段树适宜采用这种更新节点的方式{ int lc=getlchild(m),rc=getrchild(m); p[m].min=min(p[lc].min,p[rc].min); p[m].max=max(p[lc].max,p[rc].max); p[m].dis=min(p[lc].dis,p[rc].dis); if ( (p[rc].min!=M) && ((p[rc].min-p[lc].max)<p[m].dis) ) p[m].dis=p[rc].min-p[lc].max;}void insert(int m){ int m1=m+N-1;//order if (p[m1].min==M) { p[m1].min=m; p[m1].max=m; int t=getparent(m1); while (t!=0) { update(t); t=getparent(t); } }}void remove(int m){ int m1=m+N-1;//order if (p[m1].min!=M) { p[m1].min=M; p[m1].max=-M; int t=getparent(m1); while (t!=0) { update(t); t=getparent(t); } }}int main(){ //freopen("a.txt","r",stdin); //freopen("b.txt","w",stdout); int i,j,k,l,t,kk,m; cin>>t; char s[15]; for (kk=1;kk<=t;kk++) { scanf("%d",&n); init(); for (i=1;i<=n;i++) { scanf("%s",s); if (s[0]=='g') { scanf("%d",&m); insert(m); } else if (s[0]=='r') { scanf("%d",&m); remove(m); } else { if (p[1].dis==M) printf("-1\n"); else printf("%d\n",p[1].dis); } } if (kk<t) cout<<endl; } return 0;}//线段树更新节点的操作不宜使用下面的通过被修改的子节点去影响父节点的方式/*void insert(int m){ int m1=m+n1;//order if (p[m1].min==M) { p[m1].min=m; p[m1].max=m; p[m1].dis=M; int t=getparent(m1); while (t!=0) { if (p[m1].min<p[t].min) p[t].min=p[m1].min; if (p[m1].max>p[t].max) p[t].max=p[m1].max; if (p[m1].dis<p[t].dis) p[t].dis=p[m1].dis; int lc=getlchild(t),rc=getrchild(t); int ss=p[rc].min,sss=p[lc].max; if ( (p[rc].min!=M) && (p[lc].max!=-M) && ((p[rc].min-p[lc].max)<p[t].dis) ) p[t].dis=p[rc].min-p[lc].max; m1=t; t=getparent(t); } }}void remove(int m){ int m1=m+n1;//order if (p[m1].min!=M) { p[m1].min=M; p[m1].max=-M; p[m1].dis=M; int t=getparent(m1); while (t!=0) { p[t].min=M; p[t].max=-M; p[t].dis=M; if (p[m1].min<p[t].min) p[t].min=p[m1].min; if (p[m1].max>p[t].max) p[t].max=p[m1].max; if (p[m1].dis<p[t].dis) p[t].dis=p[m1].dis; int lc=getlchild(t),rc=getrchild(t); if ( (p[rc].min!=M) && (p[lc].max!=-M) && ((p[rc].min-p[lc].max)<p[t].dis) ) p[t].dis=p[rc].min-p[lc].max; m1=t; t=getparent(t); } }}*/
STL维护俩树,一个记录点,一个记录当前的各点距离,只需记录大小小邻的点的距离即可。
SOJ老是Restricted Function,蛋疼无比。。。。。
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<vector>#include<algorithm>#include<string>#include<iostream>#include<stack>#include<set>#include<map>using namespace std;set<int> a;multiset<int> b;void remove(int m){ multiset<int>::iterator mit; mit=b.find(m); b.erase(mit);//multiset中erase迭代器和erase值的效果是不同的,前者只删除一个,后者将重复值均删除。}int main(){ //freopen("a","r",stdin); int i,t,kk,m,n; cin>>t; char s[15]; for (kk=1;kk<=t;kk++) { scanf("%d",&n); a.clear(); b.clear(); set<int>::iterator it; for (i=1;i<=n;i++) { scanf("%s",s); if (s[0]=='g') { scanf("%d",&m); it=a.find(m); if (it==a.end()) { a.insert(m); if (a.size()!=1) { set<int>::iterator it1; it1=a.find(m); it1++; it=a.find(m); if (it==a.begin()) { int dis=(*it1)-(*it); b.insert(dis); } else if (it1==a.end()) { it1--;//迭代器也可以--操作 it--; int dis=(*it1)-(*it); b.insert(dis); } else { set<int>::iterator it2; it2=a.find(m); it2--; int dis=(*it1)-(*it); b.insert(dis); dis=(*it)-(*it2); b.insert(dis); dis=(*it1)-(*it2); remove(dis); } } } } else if (s[0]=='r') { scanf("%d",&m); it=a.find(m); if (it!=a.end()) { if (a.size()!=1) { set<int>::iterator it1; it1=a.find(m); it1++; it=a.find(m); if (it==a.begin()) { int dis=(*it1)-(*it); remove(dis); } else if (it1==a.end()) { it1--; it--; int dis=(*it1)-(*it); remove(dis); } else { set<int>::iterator it2; it2=a.find(m); it2--; int dis=(*it1)-(*it); remove(dis); dis=(*it)-(*it2); remove(dis); dis=(*it1)-(*it2); b.insert(dis); } } a.erase(it); } } else { if (b.size()==0) printf("-1\n"); else printf("%d\n",*b.begin()); } } if (kk<t) printf("\n"); } return 0;}
- SOJ1802 Atomic Nucleus Investigation
- sicily 1802. Atomic Nucleus Investigation
- Atomic Nucleus Investigation 线段树
- sicily 1802. Atomic Nucleus Investigation
- sicily 1802. Atomic Nucleus Investigation
- Sicily 1802. Atomic Nucleus Investigation
- Sicily 1802 Atomic Nucleus Investigation(线段树)
- Nucleus
- Atomic
- atomic
- Atomic
- LNB investigation
- HLS Investigation
- Nucleus PLUS
- Nucleus学习
- nucleus学习
- Product Investigation on Saturday
- 征信 credit investigation
- 直接在包中创建用例
- 电能质量监测装置界面实例
- eclipse package,source folder,folder区别及相互转换
- sql plus操作oracel(windows平台)基础之简易新手篇
- poj-2406kmp中next指针
- SOJ1802 Atomic Nucleus Investigation
- Linux根目录下的四类文件夹
- DLL导出变量
- Linux socket编程学习初步(3)--客户端向服务器请求文件
- 对strcpy优化的一个核心要点
- JDBC高级应用之数据源(连接池)
- 使用linux过程中使用频率最高的命令
- sql 多表查询中,算出某些字段的总和
- HDU 3535 混合背包