• splay模板


    模板是从http://blog.csdn.net/crazy_ac/article/details/8034190这位大爷博客里找到的。。。但是在由于是功能挺全的一个版本,在一些题里可能维护了一些不必要的值(可能自己在操作步骤写丑了= =)而导致超时。。所以使用的时候还是要注意一下。。

    上模板。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 const int inf  = ~0u>>2;
      4 #define L ch[x][0]
      5 #define R ch[x][1]
      6 #define KT (ch[ ch[rt][1] ][0])
      7 const int maxn = 500010;
      8 int lim;
      9 struct SplayTree {
     10     int sz[maxn];
     11     int ch[maxn][2];
     12     int pre[maxn];
     13     int rt,top;
     14     inline void up(int x){
     15         sz[x]  = cnt[x]  + sz[ L ] + sz[ R ];
     16     }
     17     inline void Rotate(int x,int f){
     18         int y=pre[x];
     19         ch[y][!f] = ch[x][f];
     20         pre[ ch[x][f] ] = y;
     21         pre[x] = pre[y];
     22         if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;
     23         ch[x][f] = y;
     24         pre[y] = x;
     25         up(y);
     26     }
     27     inline void Splay(int x,int goal){//将x旋转到goal的下面
     28         while(pre[x] != goal){
     29             if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);
     30             else   {
     31                 int y=pre[x],z=pre[y];
     32                 int f = (ch[z][0]==y);
     33                 if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
     34                 else Rotate(y,f),Rotate(x,f);
     35             }
     36         }
     37         up(x);
     38         if(goal==0) rt=x;
     39     }
     40     inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
     41         int x=rt;
     42         while(sz[ L ] != k-1) {
     43             if(k < sz[ L ]+1) x=L;
     44             else {
     45                 k-=(sz[ L ]+1);
     46                 x = R;
     47             }
     48         }
     49         Splay(x,goal);
     50     }
     51     inline void vist(int x){
     52         if(x){
     53             printf("结点%2d : 左儿子  %2d   右儿子  %2d   val:%2d sz=%d  cnt:%d
    ",x,L,R,val[x],sz[x],cnt[x]);
     54             vist(L);
     55             vist(R);
     56         }
     57     }
     58     void debug() {
     59         puts("");
     60         vist(rt);
     61         puts("");
     62     }
     63     inline void Newnode(int &x,int c,int f){
     64         x=++top;
     65         L = R = 0;
     66         pre[x] = f;
     67         sz[x]=1; cnt[x]=1;
     68         val[x] = c;
     69     }
     70     inline void init(){
     71         ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
     72         rt=top=0; cnt[0]=0;
     73     }
     74     inline void Insert(int &x,int key,int f){
     75         if(!x) {
     76             Newnode(x,key,f);
     77             Splay(x,0);//注意插入完成后splay
     78             return ;
     79         }
     80         if(key==val[x]){
     81             cnt[x]++;
     82             sz[x]++;
     83             Splay(x,0);//注意插入完成后splay
     84             return ;
     85         }else if(key<val[x]) {
     86             Insert(L,key,x);
     87         } else {
     88             Insert(R,key,x);
     89         }
     90         up(x);
     91     }
     92     void Del_root(){//删除根节点
     93         int t=rt;
     94         if(ch[rt][1]) {
     95             rt=ch[rt][1];
     96             RTO(1,0);
     97             ch[rt][0]=ch[t][0];
     98             if(ch[rt][0]) pre[ch[rt][0]]=rt;
     99         }
    100         else rt=ch[rt][0];
    101         pre[rt]=0;
    102         up(rt);
    103     }
    104     void findpre(int x,int key,int &ans){//找前驱节点
    105         if(!x)  return ;
    106         if(val[x] <= key){
    107             ans=x;
    108             findpre(R,key,ans);
    109         } else
    110             findpre(L,key,ans);
    111     }
    112     void findsucc(int x,int key,int &ans){//找后继节点
    113         if(!x) return ;
    114         if(val[x]>=key) {
    115             ans=x;
    116             findsucc(L,key,ans);
    117         } else
    118             findsucc(R,key,ans);
    119     }
    120     inline int find_kth(int x,int k){ //第k小的数
    121         if(k<sz[L]+1) {
    122             return find_kth(L,k);
    123         }else if(k > sz[ L ] + cnt[x] ) 
    124             return find_kth(R,k-sz[L]-cnt[x]);
    125         else{ 
    126             Splay(x,0);
    127             return val[x];
    128         }
    129     }
    130     int find(int x,int key){
    131         if(!x) return 0;
    132         else if(key < val[x])  return find(L,key);
    133         else if(key > val[x])  return find(R,key);
    134         else return x;
    135     }
    136     int getmin(int x){
    137         while(L) x=L;    return val[x];
    138     }
    139     int getmax(int x){
    140         while(R) x=R;   return val[x];
    141     }
    142     //确定key的排名
    143     int getrank(int x,int key,int cur){//cur:当前已知比要求元素(key)小的数的个数
    144         if(key == val[x])  
    145             return sz[L] + cur + 1;
    146         else if(key < val[x])
    147             getrank(L,key,cur);
    148         else 
    149             getrank(R,key,cur+sz[L]+cnt[rt]);
    150     }
    151     int get_lt(int x,int key){//小于key的数的个数 lt:less than 
    152         if(!x) return 0;
    153         if(val[x]>=key) return get_lt(L,key);
    154         return cnt[x]+sz[L]+get_lt(R,key);
    155     }
    156     int get_mt(int x,int key){//大于key的数的个数 mt:more than
    157         if(!x) return 0;
    158         if(val[x]<=key) return get_mt(R,key) ;
    159         return cnt[x]+sz[R]+get_mt(L,key);
    160     }
    161     void del(int &x,int f){//删除小于lim的所有的数所在的节点
    162         if(!x) return ;
    163         if(val[x]>=lim){
    164             del(L,x);
    165         } else {
    166             x=R; 
    167             pre[x]=f;
    168             if(f==0)  rt=x;
    169             del(x,f);
    170         }
    171         if(x)  up(x);
    172     }
    173     inline void update(){
    174         del(rt,0);
    175     }
    176     int get_mt(int key) {
    177         return get_mt(rt,key);
    178     }
    179     int get_lt(int key) {
    180         return get_lt(rt,key);
    181     }
    182     void insert(int key) {
    183         Insert(rt,key,0);
    184     }
    185     void Delete(int key) {
    186         int node=find(rt,key);
    187         Splay(node,0);
    188         cnt[rt]--;
    189         if(!cnt[rt])Del_root();
    190     }
    191     int kth(int k) {
    192         return find_kth(rt,k);
    193     }
    194     int cnt[maxn];
    195     int val[maxn];
    196     int lim;
    197 }spt;
    View Code

     建树时候的函数

     1 void built(int &x,int l,int r,int father)
     2     {
     3         if(l>r)
     4         return ;
     5         int mid=(l+r)/2;
     6         Newnode(x,a[mid],father);
     7         if(l<mid)
     8         built(ch[x][0],l,mid-1,x);
     9         if(r>mid)
    10         built(ch[x][1],mid+1,r,x);
    11         up(x);
    12     }
    View Code

    然后是自己在poj3468中参照cxlove大爷改的lazy版本。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 const int inf  = ~0u>>2;
      4 #define L ch[x][0]
      5 #define R ch[x][1]
      6 #define KT (ch[ ch[rt][1] ][0])
      7 #define ll long long
      8 const int maxn = 100010;
      9 int lim;
     10 int a[maxn],n;
     11 ll lazy[maxn],sum[maxn];
     12 using namespace std;
     13 struct SplayTree {
     14     int sz[maxn];
     15     int ch[maxn][2];
     16     int pre[maxn];
     17     int rt,top;
     18     inline void up(ll x){
     19         sz[x]  =sz[ L ] + sz[ R ]+1;
     20         sum[x] = val[x] + sum[L]+sum[R]+lazy[x];
     21     }
     22     inline void pushdown(int x)
     23     {
     24         if(lazy[x])
     25         {
     26             if(L)
     27             {
     28                 lazy[L]+=lazy[x];
     29                 sum[L]+=lazy[x]*sz[L];
     30             }
     31             if(R)
     32             {
     33                 lazy[R]+=lazy[x];
     34                 sum[R]+=lazy[x]*sz[R];
     35             }
     36             val[x]+=lazy[x];
     37             lazy[x]=0;
     38         }
     39     }
     40     inline void Rotate(int x,int f){
     41         int y=pre[x];
     42         pushdown(x);
     43         pushdown(y);
     44         ch[y][!f] = ch[x][f];
     45         pre[ ch[x][f] ] = y;
     46         pre[x] = pre[y];
     47         if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;
     48         ch[x][f] = y;
     49         pre[y] = x;
     50         up(y);
     51     }
     52     inline void Splay(int x,int goal){//将x旋转到goal的下面
     53         pushdown(x);
     54         while(pre[x] != goal){
     55             if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);
     56             else   {
     57                 int y=pre[x],z=pre[y];
     58                 int f = (ch[z][0]==y);
     59                 if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
     60                 else Rotate(y,f),Rotate(x,f);
     61             }
     62         }
     63         up(x);
     64         if(goal==0) rt=x;
     65     }
     66     void RTO(int k,int goal) {
     67     int r=rt;
     68     pushdown(r);
     69     while(sz[ch[r][0]]!=k){
     70         if(k<sz[ch[r][0]]){
     71             r=ch[r][0];
     72         } else {
     73             k-=(sz[ch[r][0]]+1);
     74             r=ch[r][1];
     75         }
     76         pushdown(r);
     77     }
     78     Splay(r,goal);
     79 }
     80     inline void Newnode(int &x,int c,int f){
     81         x=++top;
     82         L = R = 0;
     83         pre[x] = f;
     84         sz[x]=1;
     85         lazy[x]=0;
     86         val[x] = c;
     87         sum[x]=c;
     88     }
     89     inline void init(){
     90         ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
     91         rt=top=0;
     92         Newnode(rt,-1,0);
     93         Newnode(ch[rt][1],-1,rt);
     94         sz[rt]=2;
     95         built(KT,1,n,ch[rt][1]);
     96         up(ch[rt][1]);
     97         up(rt);
     98     }
     99     /*void BulidTree(int &x,int l,int r,int father){
    100     if(l>r)
    101         return;
    102     int mid=(l+r)/2;
    103     Newnode(x,a[mid],father);
    104     if(l<mid)
    105         BulidTree(ch[x][0],l,mid-1,x);
    106     if(r>mid)
    107         BulidTree(ch[x][1],mid+1,r,x);
    108     up(x);
    109     }*/
    110     void built(int &x,int l,int r,int father)
    111     {
    112         if(l>r)
    113         return ;
    114         int mid=(l+r)/2;
    115         Newnode(x,a[mid],father);
    116         if(l<mid)
    117         built(ch[x][0],l,mid-1,x);
    118         if(r>mid)
    119         built(ch[x][1],mid+1,r,x);
    120         up(x);
    121     }
    122     void Update()
    123     {
    124         int l,r,c;
    125         scanf("%d%d%d",&l,&r,&c);
    126         RTO(l-1,0);
    127         RTO(r+1,rt);
    128         lazy[KT]+=c;
    129         sum[KT]+=c*sz[KT];
    130      } 
    131     void ask()
    132     {
    133         int l,r;
    134         scanf("%d%d",&l,&r);
    135         RTO(l-1,0);
    136         RTO(r+1,rt);
    137         printf("%lld
    ",sum[KT]);
    138     }
    139     int val[maxn];
    140 }spt;
    141 int main()
    142 {
    143     int m;
    144     scanf("%d%d",&n,&m);
    145     for(ll i=1;i<=n;i++)
    146     scanf("%d",&a[i]);
    147     spt.init();
    148     for(ll i=1;i<=m;i++)
    149     {
    150         char x;
    151         scanf(" %c",&x);
    152         if(x=='Q')
    153         spt.ask();
    154         else
    155         spt.Update();
    156     }
    157     return 0;
    158  } 
    View Code

    对于建树时使用的类似线段树的写法让我又对splay了解了许多。。。

  • 相关阅读:
    Badboy参数化
    Badboy运行脚本
    Badboy中创建Suite, test, step和Template
    美食
    Badboy录制模式
    美食
    BadBoy+JMeter来录制和运行Web测试脚本
    JMeter简介及使用JMeter来访问网站
    软件测试的艺术
    泗泾办小卡需要的材料
  • 原文地址:https://www.cnblogs.com/julyc/p/5929111.html
Copyright © 2020-2023  润新知