[ZJOI2007]报表统计 解题报告
2015-01-18 11:50
239 查看
[ZJOI2007]报表统计
Time Limit: 15 Sec Memory Limit: 162 MBDescription
小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。经过仔细观察,小Q发现统计一张报表实际上是维护一个可能为负数的整数数列,并且进行一些查询操作。在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作: INSERT i k 在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子) MIN_GAP 查询相邻两个元素的之间差值(绝对值)的最小值 MIN_SORT_GAP 查询所有元素中最接近的两个元素的差值(绝对值) 例如一开始的序列为 5 3 1 执行操作INSERT 2 9将得到: 5 3 9 1 此时MIN_GAP为2,MIN_SORT_GAP为2。 再执行操作INSERT 2 6将得到: 5 3 9 6 1 注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
Input
第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。第二行为N个整数,为初始序列。接下来的M行每行一个操作,即“INSERT i k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。Output
对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。Sample Input
3 55 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP
Sample Output
22
1
HINT
对于100%的数据,N , M ≤500000 对于所有的数据,序列内的整数不超过5*10^8。这道题又写了我一上午。。思路一开始不是很清晰,需要记录N个表头表尾,但是一开始我忘了维护表头,又忘了记录表尾。。编了一个数据结果弱得不得了根本没测出错来,导致第一遍交全WA了。
还有TLE。。原来Set.end()是遍历一遍Set容器。。如果要判是否有前驱后继的话还应该需要手动加一个MAXN和-MAXN.下道题一定要注意啦:
①写题的时候思路一定要清晰,知道自己要做什么,这句话是什么意思。
②写完以后先大体读一遍,走一遍程序的流程;多编数据,至少两个,尽量卡飞自己的程序。
③以后再也不要用.end()啦!!还是手动插入一个MAXN吧。
④Code Trick:优先队列+布尔数组≈堆+映射;以后一定都学会用!
Splay+手写堆:
#include<iostream> using namespace std; #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> char * ptr=(char *)malloc(20000000); inline void in(int &x){ bool flag=0; while(*ptr<'0'||*ptr>'9') if(*ptr++=='-') flag=1; x=0; while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0'; if(flag)x=-x; } struct HS{ int key,x; inline bool operator < (const HS a) const{ return key<a.key; } }heap[1000001]; int point[500001],heapsize,a[500001],A[500001]; inline void up(int now){ for(int next=now>>1;next&&heap[now]<heap[next];now=next,next>>=1){ point[heap[now].x]=next; point[heap[next].x]=now; swap(heap[now],heap[next]); } } inline void down(int now){ int next=now<<1; while(next<heapsize){ if(next+1<heapsize&&heap[next+1]<heap[next])++next; if(heap[now]<heap[next])return; point[heap[now].x]=next; point[heap[next].x]=now; swap(heap[now],heap[next]); now=next,next<<=1; } } #include<set> struct SS{ SS * f,* c[2]; int key; bool it; }* nil=new SS((SS){nil,nil,nil,0,0}),* root; inline void zig(SS * x,bool d){ SS * ftr=x->f; if(ftr->it)ftr->it=0,x->it=1; x->f=ftr->f; if(x->f->c[0]==ftr)x->f->c[0]=x; else x->f->c[1]=x; ftr->c[d]=x->c[!d],ftr->c[d]->f=ftr; x->c[!d]=ftr,ftr->f=x; } inline void splay(SS * x){ for(bool d;!x->it;zig(x,d)){ d=x->f->c[1]==x; if(!x->f->it&&d==(x->f->f->c[1]==x->f))zig(x->f,d); } root=x; } inline bool insert(int A){ SS * x=root; while(1){ if(A==x->key)return 1; if(A<x->key) if(x->c[0]==nil){ x->c[0]=new SS((SS){x,nil,nil,A,0}); x=x->c[0]; break; } else x=x->c[0]; else if(A>x->key) if(x->c[1]==nil){ x->c[1]=new SS((SS){x,nil,nil,A,0}); x=x->c[1]; break; } else x=x->c[1]; } splay(x); return 0; } bool flag=1; int ans=0x7fffffff; inline void I(int A){ if(insert(A)){ flag=0; ans=0; return; } SS * x; if(root->c[1]!=nil){ x=root->c[1]; while(x->c[0]!=nil)x=x->c[0]; ans=min(ans,x->key-A); } if(root->c[0]!=nil){ x=root->c[0]; while(x->c[1]!=nil)x=x->c[1]; ans=min(ans,A-x->key); } } int main(){ freopen("form.in","r",stdin); freopen("form.out","w",stdout); fread(ptr,1,20000000,stdin); int N,M,i,tot=0; in(N),in(M),in(a[1]); root=new SS((SS){nil,nil,nil,a[1],1}); heapsize=N; SS * x; for(i=1;i<N;++i){ point[i]=i; in(a[i+1]); heap[i]=(HS){abs(a[i]-a[i+1]),i}; if(flag)I(a[i+1]); } memcpy(A,a,sizeof(a)); for(i=N;--i;)down(i); int k;/* for(i=1;i<heapsize;++i)cout<<i<<":"<<heap[i].key<<" "<<heap[i].x<<"\n"; cout<<"XXXXXXX\n"; for(i=1;i<N;++i)cout<<i<<":"<<point[i]<<endl;*/ while(M--){ //cout<<"------"<<M<<"------\n"; while(*ptr!='I'&&*ptr!='M')++ptr; for(i=0;i<4;++i)++ptr; switch(*ptr){ case 'R': in(i),in(k); if(i!=N){ //if(tot>=100&&tot<=110)cout<<"A:("<<i<<")"<<a[i]<<"->"<<k<<"->"<<A[i+1]<<endl; heap[point[i]]=(HS){abs(a[i]-k),N}; point =point[i]; up(point ); down(point ); heap[point ].x=0; /* for(i=1;i<heapsize;++i)cout<<i<<":"<<heap[i].key<<" "<<heap[i].x<<"\n"; cout<<"XXXXXXX\n"; for(i=1;i<N;++i)cout<<i<<":"<<point[i]<<endl;*/ //cout<<"A:"<<abs(a[i+1]-k)<<endl; heap[heapsize]=(HS){abs(A[i+1]-k),i}; point[i]=heapsize; up(heapsize++); } else{ heap[heapsize]=(HS){abs(a[i]-k),0}; up(heapsize++); } if(flag)I(k); a[i]=k; break; case 'G':++tot;printf("%d\n",heap[1].key);break; case 'S':++tot;printf("%d\n",ans); }/* if(tot>=100&&tot<=110){ cout<<"-------"<<M<<"------\n"; cout<<heap[1].key<<" "<<ans<<":\n"; for(i=1;i<heapsize;++i)cout<<i<<":"<<heap[i].key<<" "<<heap[i].x<<"\n"; cout<<"XXXXXXX\n"; for(i=1;i<N;++i)cout<<i<<":"<<point[i]<<endl; cout<<endl; }*/ } }Set+priority_heap:
#include<iostream> using namespace std; #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> char * ptr=(char *)malloc(20000000); inline void in(int &x){ bool flag=0; while(*ptr<'0'||*ptr>'9') if(*ptr++=='-') flag=1; x=0; while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0'; if(flag)x=-x; } struct HS{ int key,x; inline bool operator < (const HS a) const{ return key>a.key; } }; int point[500000],a[500001],A[500001]; bool p[1500001]; #include<queue> priority_queue<HS> q; #include<set> #define MAXN 0x7fffffff int main(){ freopen("form.in","r",stdin); freopen("form.out","w",stdout); fread(ptr,1,20000000,stdin); int N,M,ans=MAXN,i,tot=0; in(N),in(M),in(a[1]); bool flag=1; set<int> Set; set<int>::iterator it; Set.insert(MAXN); Set.insert(a[1]); Set.insert(-MAXN); for(i=1;i<N;++i){ in(a[i+1]); point[i]=tot; q.push((HS){abs(a[i]-a[i+1]),tot++}); if(flag){ it=Set.lower_bound(a[i+1]); if(*it!=MAXN)ans=min(ans,*it-a[i+1]); if(*--it!=-MAXN)ans=min(ans,a[i+1]-*it); if(ans==0)flag=0; else Set.insert(a[i+1]); } } memcpy(A,a,sizeof(a)); int k; while(M--){ //cout<<"------"<<M<<"------\n"; while(*ptr!='I'&&*ptr!='M')++ptr; for(i=0;i<4;++i)++ptr; switch(*ptr){ case 'R': in(i),in(k); if(i!=N){ q.push((HS){abs(a[i]-k),tot++}); q.push((HS){abs(A[i+1]-k),tot}); p[point[i]]=1; point[i]=tot++; } else q.push((HS){abs(a[i]-k),tot++}); if(flag){ it=Set.lower_bound(k); if(*it!=MAXN)ans=min(ans,*it-k); if(*--it!=-MAXN)ans=min(ans,k-*it); if(ans==0)flag=0; else Set.insert(k); } a[i]=k; break; case 'G': while(p[q.top().x])q.pop(); printf("%d\n",q.top().key); break; case 'S':printf("%d\n",ans); } } }
相关文章推荐
- BZOJ大视野 1059: [ZJOI2007]矩阵游戏 解题报告
- LuoguP1131[ZJOI2007] 时态同步 解题报告【树形DP(?)】
- [ZJOI2007]棋盘制作 解题报告(最大连续同色子矩阵)
- BZOJ 1093 [ZJOI 2007] Tarjan+DAG拓扑排序DP 解题报告
- [BZOJ1040] [ZJOI2008]骑士 解题报告
- 【堆+平衡树】BZOJ1058(ZJOI2007)[报表统计]题解
- [bzoj1058][ZJOI2007][报表统计] (STL)
- 洛谷.1110.[ZJOI2007]报表统计(Multiset Heap)
- [CQOI2007]三角形tri 解题报告
- hdoj2007解题报告
- 【BZOJ - 1058】 ZJOI2007 报表统计
- [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分
- [luoguP1110] [ZJOI2007]报表统计(set暴力)
- 解题报告 APIO 2007 风铃
- hdoj2007解题报告
- bzoj1058: [ZJOI2007]报表统计(splay+堆)
- 【BZOJ1058】【ZJOI2007】报表统计
- 【BZOJ 1058】 [ZJOI2007]报表统计
- BZOJ 2007 对偶图 解题报告
- codevs 1164 || NOIP 2007 统计数字 模拟 解题报告