zoukankan      html  css  js  c++  java
  • hdu1754I Hate It(splay)

    链接

    线段树的水题,拿来学习一下splay.

    本题涉及到求最大值以及单点更新,折腾了许久,差不多把splay搞明白了。

    按位置建树,按位置是一颗排序二叉树,对于区间的操作非常方便,每次操作都将需要的结点转自根的右孩子的左孩子,因为加了2个结点,一个最小的,一个最大的,据说是为了防止越界。

    这题只有单点,所以每次将所求结点旋自根节点即可。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 200010
     12 #define LL __int64
     13 #define INF 0xfffffff
     14 #define key_value ch[ch[root][1]][0]
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 int pre[N],s[N],size[N];
     19 int ch[N][2],a[N],val[N];
     20 int root,n,tot;
     21 void newnode(int &x,int k,int fa)
     22 {
     23     x = ++tot;
     24     ch[x][0]=ch[x][1] = 0;
     25     pre[x] = fa;
     26     size[x] = 1;
     27     s[x] = k;
     28     val[x] = k;
     29 }
     30 void pushup(int w)
     31 {
     32     size[w] = size[ch[w][0]]+size[ch[w][1]]+1;
     33     s[w] = max(max(s[ch[w][0]],s[ch[w][1]]),val[w]);
     34    // cout<<s[w]<<" "<<w<<"// "<<" "<<ch[w][1]<<" "<<s[w]<<endl;
     35 }
     36 void rotate(int r,int kind)
     37 {
     38     int y = pre[r];
     39     ch[y][!kind] = ch[r][kind];
     40     pre[ch[r][kind]] = y;
     41     if(pre[y])
     42     {
     43         ch[pre[y]][ch[pre[y]][1]==y] = r;
     44     }
     45     pre[r] = pre[y];
     46     ch[r][kind] = y;
     47     pre[y] = r;
     48     pushup(y);
     49     //pushup(r);
     50 }
     51 void splay(int r,int goal)
     52 {
     53     while(pre[r]!=goal)
     54     {
     55        if(pre[pre[r]]==goal)
     56         {
     57              rotate(r,ch[pre[r]][0]==r);
     58         }
     59         else
     60         {
     61             int y = pre[r];
     62             int kind = (ch[pre[y]][0]==y);
     63             if(ch[y][kind]==r)
     64             {
     65                 rotate(r,!kind);
     66                 rotate(r,kind);
     67             }
     68             else
     69             {
     70                 rotate(y,kind);
     71                 rotate(r,kind);
     72             }
     73         }
     74     }
     75     pushup(r);
     76     if(goal==0) root = r;
     77 }
     78 int get_k(int k)
     79 {
     80     int r = root;
     81     while(size[ch[r][0]]!=k)
     82     {
     83         if(size[ch[r][0]]>k)
     84         r = ch[r][0];
     85         else
     86         {
     87             k-=(size[ch[r][0]]+1);
     88             r = ch[r][1];
     89         }
     90     }
     91     return r;
     92 }
     93 int query(int l,int r)
     94 {
     95     splay(get_k(l-1),0);
     96     splay(get_k(r+1),root);
     97     return s[key_value];
     98 }
     99 /*void update(int l,int r,int k)
    100 {
    101     splay(get_k(l-1),0);
    102     splay(get_k(r+1),root);
    103     val[key_value] = k;
    104     s[key_value] = k;
    105     pushup(ch[root][1]);
    106     pushup(root);
    107 }*/
    108 void update(int l,int r,int k)
    109 {
    110     int kk = get_k(l);
    111     val[kk] = k;
    112     splay(kk,0);
    113 }
    114 void build(int &w,int l,int r,int fa)
    115 {
    116     if(l>r) return ;
    117     int m = (l+r)>>1;
    118     newnode(w,a[m],fa);
    119     build(ch[w][0],l,m-1,w);
    120     build(ch[w][1],m+1,r,w);
    121     pushup(w);
    122 }
    123 void init()
    124 {
    125     int i;
    126     for(i = 0 ;i < n ;i++)
    127     scanf("%d",&a[i]);
    128     ch[0][0] = ch[0][1] = pre[0] = size[0] = s[0] = 0;
    129     root = tot =0;
    130     newnode(root,-1,0);
    131     newnode(ch[root][1],-1,root);
    132     size[root] = 2;
    133     build(key_value,0,n-1,ch[root][1]);
    134     pushup(ch[root][1]);
    135     pushup(root);
    136 }
    137 int main()
    138 {
    139     int q,x,y,i;
    140     char sq[10];
    141     while(scanf("%d%d",&n,&q)!=EOF)
    142     {
    143         init();
    144         while(q--)
    145         {
    146             scanf("%s%d%d",sq,&x,&y);
    147             if(sq[0]=='U')
    148             {
    149                 update(x,x,y);
    150                 /*for(i = 0; i <= n+2; i++)
    151                 cout<<ch[i][0]<<" "<<ch[i][1]<<" "<<i<<endl;
    152                 puts("");*/
    153             }
    154             else
    155             {
    156                 printf("%d
    ",query(x,y));
    157                 /*for(i = 0; i <= n+2; i++)
    158                 cout<<ch[i][0]<<" "<<ch[i][1]<<" "<<i<<endl;
    159                 puts("");*/
    160             }
    161         }
    162     }
    163     return 0;
    164 }
    View Code
  • 相关阅读:
    使用Oracle ODP.NET 11g的.NET程序发布方法
    Client使用c#和odp.net连接server oracle
    打造百度网盘备份利器:自动备份Linux VPS文件和多线程下载百度网盘资源
    安装软件:/lib/ld-linux.so.2: bad ELF interpreter解决
    ArcSDE数据库连接(直连、服务连)与GT_Geometry存
    AE的Annotation学习摘记
    Samba简单配置--匿名用户共享资料可读可写的实现
    Sublime Text 2 使用心得
    ArcGIS Server启动服务报:ERROR: Unable to start Xvfb on any port in the range 6600
    [DataContract] 和[DataMember]
  • 原文地址:https://www.cnblogs.com/shangyu/p/3787224.html
Copyright © 2011-2022 走看看