zoukankan      html  css  js  c++  java
  • [luogu1110][报表统计]

    题目链接

    思路

    set+map+优先队列就可以水过去。可以发现,每插入一个元素,都会使得操作2中原来相邻的那个差值消失,然后多了两个新的差值。对于新的差值,只要直接扔到优先队列里就好了。那么删除呢。可以用map记录一下当前元素被删除了多少次。然后查询的时候将被删除的跳过即可。对于操作3,只要将插入的数都扔到set里,然后每次插入都找出当前点的前驱后继,并用ans记录下最优的。查询的时候直接输出ans即可。
    为了证明自己真的有在练习平衡树,写了个splay代替set,然后跑的比set还慢2333。还可以再写一棵平衡树,来代替map+优先队列的操作。

    STL代码

    /*
    * @Author: wxyww
    * @Date:   2018-12-09 19:19:23
    * @Last Modified time: 2018-12-09 19:56:45
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<set>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<ctime>
    #include<queue>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    const int N = 1000000 + 100,INF = 1e9;
    map<int,int>ma;
    priority_queue<int,vector<int>,greater<int> >q;
    set<int>s;
    ll read() {
       ll x=0,f=1;char c=getchar();
       while(c<'0'||c>'9') {
          if(c=='-') f=-1;
          c=getchar();
       }
       while(c>='0'&&c<='9') {
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }
    int a[N],lianbiao[N],now[N];
    char c[20];
    set<int>::iterator k1,k2;
    int ans1 = INF,ans2 = INF;
    int main() {
       int n = read(),m = read();
       memset(a,-0x3f,sizeof(a));
       s.insert(-INF);s.insert(INF);
       for(int i = 1;i <= n;++i) {
          a[i] = read();
          lianbiao[i - 1] = i;
          k1 = --s.lower_bound(a[i]);k2 = s.lower_bound(a[i]);
    
          ans2 = min(ans2,min(abs(*k1 - a[i]),abs(*k2 - a[i])));
          q.push(abs(a[i] - a[i - 1]));
          s.insert(a[i]);
          now[i] = i;
       }
       while(m--) {
          scanf("%s",c + 1);
          if(c[1] == 'I') {
             int pos = read();
             a[++n] = read();
             int k = now[pos];
             
             ma[abs(a[k] - a[lianbiao[k]])]++;
             q.push(abs(a[n] - a[k]));q.push(abs(a[n] - a[lianbiao[k]]));
    
             k1 = --s.lower_bound(a[n]);k2 = s.lower_bound(a[n]);
             ans2 = min(ans2,min(abs(*k1 - a[n]),abs(*k2 - a[n])));
             s.insert(a[n]);
    
             now[pos] = n;
             lianbiao[n] = lianbiao[k];
             lianbiao[k] = n;
          }
          else if(c[6] == 'A') {
             int z = q.top();
             while(ma[z]) {
                q.pop();
                ma[z]--;
                z = q.top();
             }
             printf("%d
    ",z);
          }
          else printf("%d
    ",ans2);
       }
       return 0;
    }
    

    splay代码

    /*
    * @Author: wxyww
    * @Date:   2018-12-09 16:29:51
    * @Last Modified time: 2018-12-09 20:32:00
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<ctime>
    #include<bitset>
    using namespace std;
    #define ls TR[cur].ch[0]
    #define rs TR[cur].ch[1]
    typedef long long ll;
    const int N = 1000000 + 100,INF = 1e9;
    ll read() {
       ll x=0,f=1;char c=getchar();
       while(c<'0'||c>'9') {
          if(c=='-') f=-1;
          c=getchar();
       }
       while(c>='0'&&c<='9') {
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }
    struct node {
       int ch[2],val,siz,pre,cnt;
    }TR[N];
    inline void up(int cur) {
       TR[cur].siz = TR[ls].siz + TR[rs].siz + TR[cur].cnt;
    }
    int tot,rt;
    inline int getwh(int cur) {
       return TR[TR[cur].pre].ch[1] == cur;
    }
    inline void rotate(int cur) {
       int f = getwh(cur),fa = TR[cur].pre,gr = TR[fa].pre;
       TR[cur].pre = gr;
       TR[gr].ch[getwh(fa)] = cur;
       TR[TR[cur].ch[f ^ 1]].pre = fa;
       TR[fa].ch[f] = TR[cur].ch[f ^ 1];
       TR[fa].pre = cur;
       TR[cur].ch[f ^ 1] = fa;
       up(fa);up(cur);
    }
    void splay(int cur,int to) {
       while(TR[cur].pre != to) {
          if(TR[TR[cur].pre].pre != to) {
             if(getwh(cur) == getwh(TR[cur].pre)) rotate(TR[cur].pre);
             else rotate(cur);
          }
          rotate(cur);
       }
       if(!to) rt = cur;
    }
    void insert(int cur,int val,int father) {
       if(!cur) {
          cur = ++tot;
          TR[cur].pre = father;
          TR[cur].val = val;
          TR[cur].siz = TR[cur].cnt = 1;
          TR[father].ch[val > TR[father].val] = cur;
          splay(cur,0);
          return;
       }
       TR[cur].siz++;
       if(val == TR[cur].val) {TR[cur].cnt++;return;}
       insert(TR[cur].ch[val > TR[cur].val],val,cur);
    }
    inline int getpos(int val) {
       int cur = rt,lst;
       while(cur) {
          lst = cur;
          if(TR[cur].val == val) return cur;
          if(val > TR[cur].val) cur = rs;
          if(val < TR[cur].val) cur = ls;
       }
       return lst;
    }
    inline int pred(int val) {
       int cur = getpos(val);
       if(TR[cur].val <= val) return TR[cur].val;
       splay(cur,0);
       cur = ls;
       while(rs) cur = rs;
       return TR[cur].val;
    }
    inline int nex(int val) {
       int cur = getpos(val);
       if(TR[cur].val >= val) return TR[cur].val;
       splay(cur,0);
       cur = rs;
       while(ls) cur = ls;
       return TR[cur].val;
    }
    int a[N],lianbiao[N],now[N];
    char c[20];
    int ans1 = INF,ans2 = INF;
    map<int,int>ma;
    priority_queue<int,vector<int>,greater<int> >q;
    int main() {
    
       int n = read(),m = read();
       memset(a,-0x3f,sizeof(a));
       insert(rt,-INF,0);insert(rt,INF,0);
       for(int i = 1;i <= n;++i) {
          a[i] = read();
          lianbiao[i - 1] = i;
          // puts("!!");
          int k1 = pred(a[i]),k2 = nex(a[i]);
          ans2 = min(ans2,min(abs(k1 - a[i]),abs(k2 - a[i])));
          q.push(abs(a[i] - a[i - 1]));
          insert(rt,a[i],0);
          now[i] = i;
       }
       while(m--) {
          scanf("%s",c + 1);
          if(c[1] == 'I') {
             int pos = read();
             a[++n] = read();
             int k = now[pos];
             
             ma[abs(a[k] - a[lianbiao[k]])]++;
             q.push(abs(a[n] - a[k]));q.push(abs(a[n] - a[lianbiao[k]]));
    
             int k1 = pred(a[n]),k2 = nex(a[n]);
             ans2 = min(ans2,min(abs(k1 - a[n]),abs(k2 - a[n])));
             insert(rt,a[n],0);
    
             now[pos] = n;
             lianbiao[n] = lianbiao[k];
             lianbiao[k] = n;
          }
          else if(c[6] == 'A') {
             int z = q.top();
             while(ma[z]) {
                q.pop();
                ma[z]--;
                z = q.top();
             }
             printf("%d
    ",z);
          }
          else printf("%d
    ",ans2);
       }
       return 0;
    }
    

    一言

    积极者相信只有推动自己才能推动世界,只要推动自己就能推动世界。

  • 相关阅读:
    epoll的LT和ET模式
    linux搭建java环境
    【第三方SDK】百度地图实现最简单的定位功能(无地图界面)
    闲云控制台(二)查看文件功能,支持十六进制查看文件
    ios8 swift开发:显示变量的类名称
    cocos2dx的runAction: 反复运行,多个动作连接运行,多个动作同一时候运行的实现
    myeclipse设置凝视
    2-06. 数列求和(20)(ZJUPAT 数学)
    【IPC进程间通信之四】数据复制消息WM_COPYDATA
    条件熵定义推导公式
  • 原文地址:https://www.cnblogs.com/wxyww/p/10093243.html
Copyright © 2011-2022 走看看