P1110 [ZJOI2007]报表统计
題目描述
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為22,MIN_SORT_GAP為22。
再執行操作INSERT 2 6將得到:5, 3, 9, 6, 1
注意這個時候原序列的第2個元素后面已經添加了一個9,此時添加的6應加在9的后面。這個時候MIN_GAP為2,MIN_SORT_GAP為1。
于是小Q寫了一個程序,使得程序可以自動完成這些操作,但是他發現對于一些大的報表他的程序運行得很慢,你能幫助他改進程序么?
輸入輸出格式
輸入格式:
?
第一行包含兩個整數N,M,分別表示原數列的長度以及操作的次數。
第二行為N個整數,為初始序列。
接下來的M行每行一個操作,即INSERT i k,MIN_GAP,MIN_SORT_GAP?中的一種(無多余空格或者空行)。
?
輸出格式:
?
對于每一個MIN_GAP和MIN_SORT_GAP命令,輸出一行答案即可。
?
輸入輸出樣例
輸入樣例#1:?3 5 5 3 1 INSERT 2 9 MIN_SORT_GAP INSERT 2 6 MIN_GAP MIN_SORT_GAP 輸出樣例#1:?
2 2 1
說明
對于30%的數據,N ≤ 1000?,M ≤ 5000
對于100%的數據,N ,M ≤500000
對于所有的數據,序列內的整數不超過5×108。
時限2s
?
Solution:
本題splay+堆(好水啊,亂打的代碼都能AC~)。
分析題目:
操作1,加入一個數,只會改變相鄰的關系,所以數組模擬隨便亂搞維護下相鄰關系。
操作2,加入一個數,改變的是兩對相鄰的差值,所以可以直接用帶修改的堆去維護(pbds大法好!)。
操作3,由于是維護全局最小值,那么只需要在加入數時,在其插入二叉搜索樹的遍歷過程中,與訪問過的節點更新下答案,當然為了保證樹的平衡,選用平衡樹寫寫就行了。
代碼:
/*Code by 520 -- 9.17*/ #include<bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/priority_queue.hpp> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--) #define son(x) (x==ch[fa[x]][1]) using namespace std; using namespace __gnu_pbds; const int N=1000005; int n,m,a[N<<1][2],tot,val[N<<1]; int root,ch[N][2],fa[N],cnt,date[N]; int minn=0x7fffffff; struct node{int ls,rs,val;bool operator < (const node &a) const {return val>a.val;} }; typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap; heap q; heap::point_iterator id[N];int gi(){int a=0;char x=getchar();bool f=0;while((x<'0'||x>'9')&&x!='-') x=getchar();if(x=='-') x=getchar(),f=1;while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();return f?-a:a; }il void rotate(int x){int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];z?ch[z][c]=x:root=x; fa[x]=z;if(a) fa[a]=y; ch[y][b]=a;ch[x][!b]=y,fa[y]=x; }il void splay(int x,int i){while(fa[x]!=i){RE int y=fa[x],z=fa[y];if(z==i) rotate(x);else {if(son(x)==son(y)) rotate(y),rotate(x);else rotate(x),rotate(x);}} }void insert(int &rt,int x){if(!rt) {rt=++cnt,date[cnt]=x;return;}if(date[rt]==x) {minn=0;return;}if(x<date[rt])insert(ch[rt][0],x),fa[ch[rt][0]]=rt,minn=min(minn,abs(date[rt]-x));else insert(ch[rt][1],x),fa[ch[rt][1]]=rt,minn=min(minn,abs(date[rt]-x)); }int main(){int pos,x; char s[10];n=gi(),m=gi(),tot=n;For(i,1,n) {val[i]=gi(),insert(root,val[i]),splay(cnt,0);if(i!=1) a[i][0]=i;if(i!=n) a[i][1]=i;}For(i,2,n) id[i]=q.push(node{i,i+1,abs(val[i]-val[i-1])});while(m--){scanf("%s",s);if(s[0]=='I') {pos=gi(),val[++tot]=gi(),insert(root,val[tot]),splay(cnt,0);int tp=a[pos][1];id[tot]=q.push(node{tot,tp,abs(val[tp]-val[tot])});if(pos!=n) q.modify(id[pos+1],node{pos+1,tot,abs(val[pos+1]-val[tot])});a[pos+1][0]=tot,a[pos][1]=tot;}else if(strlen(s)==7) printf("%d\n",q.top().val);else printf("%d\n",minn);}return 0; }?
轉載于:https://www.cnblogs.com/five20/p/9665522.html
總結
以上是生活随笔為你收集整理的P1110 [ZJOI2007]报表统计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: maven 引入外部jar包的几种方式
- 下一篇: 六月中旬的心得