zoukankan      html  css  js  c++  java
  • BZOJ 1058 [ZJOI2007]报表统计 Splay

    这个题真是不爽,人家set又短又快,我这个又长又慢,差十几毫秒tle。。。

    我是一个splay维护相邻的最差小值,一个是维护全局最小差值(在插入的时候用前驱和后继更新)

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cstdlib>
      6 #include <cmath>
      7 
      8 #define N 2222222
      9 #define INF 1LL<<60
     10 
     11 using namespace std;
     12 
     13 long long msg,num[N],val[N],a[N],b[N];
     14 int fa[N],son[N][2];
     15 int tot,cnt,root1,root2;
     16 int q[N],top;
     17 int n,m;
     18 int hs[N],lt[N],rt[N];
     19 
     20 inline void prt(int x)
     21 {
     22     if(!x) return;
     23     prt(son[x][0]);
     24     printf("%lld    ",val[x]);
     25     prt(son[x][1]);
     26 }
     27 
     28 inline void link(int x,int y,int c)
     29 {
     30     fa[x]=y; son[y][c]=x;
     31 }
     32 
     33 inline void rotate(int x,int c)
     34 {
     35     int y=fa[x];
     36     link(x,fa[y],son[fa[y]][1]==y);
     37     link(son[x][!c],y,c);
     38     link(y,x,!c);
     39 }
     40 
     41 inline void splay(int x,int g,int &rt)
     42 {
     43     while(fa[x]!=g)
     44     {
     45         int y=fa[x];
     46         int cy=son[fa[y]][1]==y,cx=son[y][1]==x;
     47         if(fa[y]==g) rotate(x,cx);
     48         else
     49         {
     50             if(cx==cy) rotate(y,cy);
     51             else rotate(x,cx);
     52             rotate(x,cy);
     53         }
     54     }
     55     if(!g) rt=x;
     56 }
     57 
     58 inline int getnum()
     59 {
     60     if(top) return q[top--];
     61     return ++cnt;
     62 }
     63 
     64 inline void newnode(int y,int &x,long long sp)
     65 {
     66     x=getnum();
     67     fa[x]=y; val[x]=sp;
     68     son[x][0]=son[x][1]=0;
     69 }
     70 
     71 inline void init()
     72 {
     73     newnode(cnt=0,root1,-INF);
     74     newnode(root1,son[root1][1],INF);
     75     newnode(0,root2,-INF);
     76     newnode(root2,son[root2][1],INF);
     77 }
     78 
     79 inline void build(int &u,int l,int r,int f)
     80 {
     81     if(l>r) return;
     82     int mid=(l+r)>>1;
     83     newnode(f,u,a[mid]);
     84     build(son[u][0],l,mid-1,u);
     85     build(son[u][1],mid+1,r,u);
     86 }
     87 
     88 inline void insert(long long sp,int &rt)
     89 {
     90     int x=rt;
     91     while(son[x][sp>val[x]]) x=son[x][sp>val[x]];
     92     newnode(x,son[x][sp>val[x]],sp);
     93     splay(son[x][sp>val[x]],0,rt);
     94 }
     95 
     96 inline int find(long long sp,int rt)
     97 {
     98     int x=rt;
     99     while(x)
    100     {
    101         if(val[x]==sp) return x;
    102         x=son[x][sp>val[x]];
    103     }
    104 }
    105 
    106 inline int getmax(int x)
    107 {
    108     while(son[x][1]) x=son[x][1];
    109     return x;
    110 }
    111 
    112 inline int getmin(int x)
    113 {
    114     while(son[x][0]) x=son[x][0];
    115     return x;
    116 }
    117 
    118 inline void del(long long sp,int &rt)
    119 {
    120     int z=find(sp,rt),x,y;
    121     splay(z,0,rt);
    122     x=getmax(son[z][0]);
    123     y=getmin(son[z][1]);
    124     splay(x,0,rt); splay(y,x,rt);
    125     q[++top]=son[y][0];
    126     fa[son[y][0]]=0;
    127     son[y][0]=0;
    128 }
    129 
    130 inline void go()
    131 {
    132     msg=INF;
    133     scanf("%d%d",&n,&m);
    134     for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
    135     for(int i=1;i<n;i++) a[i]=abs(b[i+1]-b[i]);
    136     sort(a+1,a+n);
    137     init();
    138     build(son[son[root1][1]][0],1,n-1,son[root1][1]);
    139     for(int i=1;i<=n;i++) a[i]=b[i];
    140     sort(a+1,a+1+n);
    141     for(int i=1;i<n;i++) msg=min(msg,abs(a[i]-a[i+1]));
    142     build(son[son[root2][1]][0],1,n,son[root2][1]);
    143     for(int i=1;i<=n;i++)
    144     {
    145         num[i]=b[i]; hs[i]=i;
    146         lt[i]=i-1; rt[i-1]=i;
    147         lt[i+1]=i; rt[i]=i+1;
    148     }
    149     tot=n+1;
    150     char str[14]; int c; long long d;
    151     while(m--)
    152     {
    153         scanf("%s",str);
    154         if(str[0]=='I')
    155         {
    156             scanf("%d%lld",&c,&d);
    157             insert(d,root2);
    158             if(msg!=0)
    159             {
    160                 int x=getmax(son[root2][0]),y=getmin(son[root2][1]);
    161                 msg=min(msg,min(abs(val[x]-d),abs(val[y]-d)));
    162             }
    163             if(rt[hs[c]]!=n+1) del(abs(num[hs[c]]-num[rt[hs[c]]]),root1);
    164             ++tot; num[tot]=d;
    165             lt[tot]=hs[c]; lt[rt[hs[c]]]=tot;
    166             rt[tot]=rt[hs[c]]; rt[hs[c]]=tot;
    167             hs[c]=tot;
    168             if(lt[hs[c]]!=0) insert(abs(num[hs[c]]-num[lt[hs[c]]]),root1);
    169             if(rt[hs[c]]!=n+1) insert(abs(num[hs[c]]-num[rt[hs[c]]]),root1);
    170         }
    171         else if(str[4]=='G')
    172         {
    173             splay(1,0,root1);splay(2,1,root1);
    174             printf("%lld\n",val[getmin(son[2][0])]);
    175         }
    176         else printf("%lld\n",msg);
    177     }
    178 }
    179     
    180 
    181 int main()
    182 {
    183     go();
    184     return 0;
    185 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    机器重装后几个要记的问题
    JS中split用法和数组中元素的删除
    免费软件的盈利方式
    web程序的发布及相关问题
    无法直接启动带有“类库输出类型”的项目
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
    orcale不同版本数据导入、导出及库版本查询
    VSc# web程序:gridview保存Excel文件遇到的问题
    油田生产中的几个“三”
    web跨页面传值——FORM表单(c#)
  • 原文地址:https://www.cnblogs.com/proverbs/p/2956846.html
Copyright © 2011-2022 走看看