您的位置:首页 > 其它

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;  
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: