CSU队长的原创题 - 协会的账目 treap+优先队列
2013-08-24 11:48
246 查看
题意:
我觉得题目有些没说清楚....是这样的...比如样例开始是 5 3 1 , 然后变成 5 3 9 1 ,然后变成 5 3 9 6 1...询问要注意.最小值是说任意两个的..而最大值是值相邻的..
题解:
这两个问题用两种数据结构分别维护..相邻最大值用优先队列...所有数两两的最小值用treap...很基本的操作...
Program:
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<math.h> #include<queue> #define MAXN 1000005 #define MAXM 5000005<<3 #define oo 2000000000 #define ll long long using namespace std; struct node { int x,y,w; bool operator <(node a)const { return w<a.w; } }h; priority_queue<node> Q; char s[105]; int a[MAXN],_next[MAXN],_link[MAXN]; struct treap { struct node { int l,r,key,fix,size; }h[MAXN]; int root,num; void initial() { srand((int)time(0)),num=root=0; } void rot_l(int &x) { int R=h[x].r,L=h[x].l; h[x].size=h[x].size-h[R].size+h[h[R].l].size; h[R].size+=h[L].size+1; h[x].r=h[R].l,h[R].l=x; x=R; } void rot_r(int &x) { int L=h[x].l,R=h[x].r; h[x].size=h[x].size-h[L].size+h[h[L].r].size; h[L].size+=h[R].size+1; h[x].l=h[L].r,h[L].r=x; x=L; } bool insert(int &k,int key) { if (!k) { k=++num; h[k].l=h[k].r=0,h[k].size=1; h[k].key=key,h[k].fix=rand(); return true; } if (h[k].key==key) return false; if (h[k].key>key) { if (!insert(h[k].l,key)) return false; h[k].size++; if (h[h[k].l].fix>h[k].fix) rot_r(k); return true; }else { if (!insert(h[k].r,key)) return false; h[k].size++; if (h[h[k].r].fix>h[k].fix) rot_l(k); return true; } } int count(int key) { int g=0,k=root; while (k) { if (h[k].key>key) k=h[k].l; else g+=h[h[k].l].size+1,k=h[k].r; } return g; } int k_th(int kth) { int g=0,k=root; if (h[root].size<kth) return -1; while (h[h[k].l].size+g+1!=kth) { if (h[h[k].l].size+g+1>=kth) k=h[k].l; else g+=h[h[k].l].size+1,k=h[k].r; } return h[k].key; } }T; int update(int p,int key) { int k=T.count(key),h,hh; if (!k) h=T.k_th(1); else if (k==p-1) h=T.k_th(p-1); else { h=T.k_th(k); hh=T.k_th(k+1); if (key-h>hh-key) h=hh; } T.insert(T.root,key); return abs(h-key); } int main() { int i,n,m,num,ans2; while (~scanf("%d%d",&n,&m)) { for (i=1;i<=n;i++) scanf("%d",&a[i]),_next[i]=i+1,_link[i]=i; while (!Q.empty()) Q.pop(); for (i=1;i<n;i++) { h.x=i,h.y=i+1,h.w=abs(a[i]-a[i+1]); Q.push(h); } ans2=oo,T.initial(); T.insert(T.root,a[1]); for (i=2;i<=n;i++) ans2=min(ans2,update(i-1,a[i])); num=n; while (m--) { scanf("%s",s); if (s[0]=='I') { int x,y; scanf("%d%d",&x,&y); ans2=min(ans2,update(num,y)); _next[_link[x]]=++num,a[num]=y,_next[num]=x+1; h.x=_link[x],h.y=num,h.w=abs(a[num]-a[_link[x]]); Q.push(h); if (x+1<=n) { h.x=num,h.y=x+1,h.w=abs(a[x+1]-a[num]); Q.push(h); } _link[x]=num; }else if (s[1]=='a') { do { h=Q.top(); Q.pop(); }while (_next[h.x]!=h.y); Q.push(h); printf("%d\n",h.w); } else printf("%d\n",ans2); } } return 0; }
相关文章推荐
- CSU 1588 合并果子(优先队列)
- CSU 1639 队长,我想进集训队!
- CSU 1811 Tree Intersection(Treap启发式合并)
- 文章标题 CSU 1815 : Enterprising Escape(BFS--优先队列)
- CSU 1090: Number Transformation 一个非常好的优先队列打表
- CSUOJ 1726 你经历过绝望吗?两次!(BFS + 优先队列)
- CSU 1588 合并果子(贪心 优先队列)
- csu 1306 Manor(优先队列)
- Codeforces contest 883 problem L. Berland.Taxi(Treap+优先队列)
- CSU 1350 To Add Which? 给序列增加最少的值使得相邻数差<=D 优先队列+贪心
- POJ 1442(treap || 优先队列)
- CSU 1639 队长,我想进集训队!
- CSU 1726: 你经历过绝望吗?两次! <BFS,优先队列求解>
- 【原创】使用blockUI制作自定义的漂亮的网页提示框(代替confirm和alert)
- 【原创】XNA 4.0学习知识记录(1)
- 金额查错:某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某1笔或几笔, 如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗?
- 原创文章
- 关于JAVA中事件分发和监听机制实现的代码实例-绝对原创实用
- 堆(优先队列)基础
- 【原创】【狗眼看股】【2008-3-16】股市的基本运行规律