zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers splay

    题意:给你一个数列,区间更新和区间询问

    解题思路:splay指针版撸的,4700 ms险过

    解题代码:

      1 // File Name: spoj3468.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年11月05日 星期三 19时40分26秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 #define maxn 100010
     26 using namespace std;
     27 int num[maxn];
     28 struct Splaynode{
     29      struct node{
     30         struct node *pre,*ch[2];
     31         LL add;
     32         LL sum; 
     33         LL val; 
     34         LL size;
     35      }*root;
     36      node *newnode(int c)
     37      {
     38         node * p = (node*)malloc(sizeof(node));
     39         p->pre = p->ch[0] = p->ch[1] = NULL;
     40         p->sum = p->val = c ;
     41         p->size = 1 ; 
     42         p->add = 0 ;
     43         return p ;
     44      }
     45      void push_down(node *x)
     46      {
     47         //printf("push_down***%lld
    ",x->val);
     48         x->val += x->add;
     49         if(x->ch[0] != NULL)
     50         {
     51            x->ch[0]->sum += x->ch[0]->size * x->add;
     52            x->ch[0]->add += x->add;
     53         }
     54         if(x->ch[1] != NULL)
     55         {
     56            x->ch[1]->sum += x->ch[1]->size * x->add;
     57            x->ch[1]->add += x->add;
     58         }
     59         x->add = 0 ; 
     60      }
     61      void push_up(node *x)
     62      {
     63         x->size = 1;
     64         x->sum = x->val + x->add; 
     65         if(x->ch[0] != NULL)
     66         {
     67            x->size += x->ch[0]->size; 
     68            x->sum += x->ch[0]->sum;
     69         }
     70         if(x->ch[1] != NULL)
     71         {
     72            x->size += x->ch[1]->size;
     73            x->sum += x->ch[1]->sum;
     74         }
     75      }
     76      void print(node *x)
     77      {
     78          if(x == NULL)
     79              return;
     80          print(x->ch[0]);
     81          printf("%lld(%lld) ",x->val,x->sum);
     82          print(x->ch[1]);
     83          push_up(x);
     84      }
     85      void build(node *&x ,int l , int r ,node *f) //这里需要传递一个引用
     86      {
     87      //  printf("%d %d
    ",l,r);
     88        if(l > r )
     89            return ; 
     90        int m = (l + r )  >> 1; 
     91        x = newnode(num[m]);
     92        build(x->ch[0],l,m-1,x);
     93        build(x->ch[1],m+1,r,x);
     94        x->pre = f ;
     95        push_up(x);
     96      }
     97      void init(int n)
     98      {
     99        root = NULL;
    100        root = newnode(-1);
    101        root->ch[1]=newnode(-1);
    102        root->ch[1]->pre = root;
    103        root->size = 2;
    104        for(int i = 1;i <= n;i ++)
    105          scanf("%d",&num[i]);
    106        build(root->ch[1]->ch[0],1,n,root->ch[1]);
    107        push_up(root->ch[1]);
    108        push_up(root);
    109      }
    110      void Rotate(node *x ,int c)
    111      {
    112        node *y = x->pre;
    113        //printf("%lld %lld
    ",y->val,x->val);
    114        push_down(y);
    115        push_down(x);
    116        y->ch[!c] = x->ch[c];
    117        if(x->ch[c] != NULL)  x->ch[c]->pre = y; 
    118        x->pre = y->pre;
    119        if(y->pre != NULL)
    120        {
    121            if(y->pre->ch[0] == y) y->pre->ch[0] = x ;
    122            else y->pre->ch[1] = x ; 
    123        }
    124        x->ch[c] = y,y->pre = x; 
    125        push_up(y);
    126      }
    127      void Delete(node *x)
    128      {
    129          if(x == NULL)
    130              return;
    131          Delete(x->ch[0]);
    132          Delete(x->ch[1]);
    133          //printf("%lld
    ",x->val);
    134          free(x);
    135          x = NULL;
    136          if(x != NULL)
    137              printf("****
    ");
    138          //x = NULL;
    139          //printf("%lld
    ",x->val);
    140      }
    141      void Splay(node *x ,node *f)
    142      {
    143        //printf("****
    ");
    144        push_down(x); //为何要push_down
    145       // printf("****
    ");
    146        for(; x->pre != f ;)
    147          if(x ->pre->pre == f)
    148          { 
    149              if(x->pre-> ch[0] == x)
    150                 Rotate(x,1);
    151              else Rotate(x,0);
    152          }else{
    153             node *y = x->pre ,*z = y ->pre;
    154             if(z->ch[0] == y)
    155             {
    156                 if(y->ch[0] == x)
    157                     Rotate(y,1),Rotate(x,1);
    158                 else Rotate(x,0),Rotate(x,1);
    159             }else{
    160                 if(y->ch[1] == x)
    161                     Rotate(y,0),Rotate(x,0);
    162                 else
    163                     Rotate(x,1),Rotate(x,0);
    164             }
    165          }
    166        push_up(x);
    167        if(f == NULL) root = x;
    168      }
    169      void Rotateto(int k ,node *goal)
    170      {
    171          node *x  = root;
    172          push_down(x);
    173          while(1)
    174          {
    175             if((x->ch[0] == NULL &&k == 0) || (x->ch[0]!= NULL && x->ch[0]->size == k))
    176                 break;
    177             if(x->ch[0] !=NULL && k < x->ch[0]->size)
    178             {
    179                 x = x->ch[0];
    180             }else{
    181                 k -= ((!x->ch[0])?1:x->ch[0]->size+1); 
    182                 x = x->ch[1];
    183             }
    184             push_down(x);
    185    //        printf("%lld %lld %d
    ",x->val,x->size,k);
    186          }
    187         // printf("****
    ");
    188          //printf("%lld
    ",x->pre->val);
    189          Splay(x,goal);
    190      }
    191      void update()
    192      {
    193         int l , r, c; 
    194         scanf("%d %d %d",&l,&r,&c);
    195         Rotateto(l-1,NULL);
    196         Rotateto(r+1,root);
    197         root->ch[1]->ch[0]->add += c; 
    198         root->ch[1]->ch[0]->sum += root->ch[1]->ch[0]->size * c; 
    199      }
    200      void query()
    201      {
    202        int l , r; 
    203        scanf("%d %d",&l,&r);
    204        Rotateto(l-1,NULL);
    205     //   print(root);
    206       // printf("
    ");
    207        Rotateto(r+1,root);
    208       // print(root);
    209       // printf("
    ");
    210       // printf("****
    ");
    211        printf("%lld
    ",root->ch[1]->ch[0]->sum);
    212      }
    213 
    214 }sp;
    215 
    216 int main(){
    217     int n ,m;
    218     scanf("%d %d",&n,&m);
    219     sp.init(n);    
    220     //sp.print(sp.root);;
    221 //    printf("
    ");
    222     while(m--)
    223     {
    224        char op[10];
    225        scanf("%s",op);
    226        if(op[0] == 'Q')
    227        {
    228           sp.query();
    229        }else {
    230           sp.update();
    231        }
    232     }
    233 //    while()
    234     return 0;
    235 }
    View Code

     常数大概是线段树的3-4倍

    又用数组写了一发

      1 // File Name: poj3468.sz.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年11月07日 星期五 08时45分48秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 #define maxn 100010
     26 using namespace std;
     27 #define keytree ch[ch[root][1]][0]
     28 struct SplayTree{
     29    int sz[maxn];   //大小
     30    int ch[maxn][2];  //儿子
     31    int pre[maxn]; //父亲
     32    int root ,top1,top2; 
     33    int ss[maxn],que[maxn];
     34    inline void Rotate(int x ,int f){
     35        int y = pre[x];
     36        push_down(y);
     37        push_down(x);
     38        ch[y][!f] = ch[x][f]; 
     39        pre[ch[x][f]] = y ; 
     40        pre[x] = pre[y];
     41        if(pre[x])
     42            ch[pre[y]][ch[pre[y]][1] == y] = x; 
     43        ch[x][f] = y ; 
     44        pre[y] = x; 
     45        push_up(y);
     46    }
     47    void Splay(int x, int goal){
     48       push_down(x);
     49       while(pre[x] != goal){
     50          if(pre[pre[x]] == goal){
     51             Rotate(x,ch[pre[x]][0] == x);
     52          }else{
     53             int y = pre[x],z = pre[y];
     54             int f = (ch[z][0] == y);
     55             if(ch[y][f] == x)
     56             {
     57                 Rotate(x,!f),Rotate(x,f);
     58             }else{
     59                 Rotate(y,f),Rotate(x,f);
     60             }
     61          }
     62       }
     63       push_up(x);
     64       if(goal == 0 ) root = x; 
     65    }
     66    void Rotateto(int k ,int goal)
     67    {
     68       int x = root; 
     69       push_down(x);
     70       while(sz[ch[x][0]] != k){
     71          if(k < sz[ch[x][0]])
     72          {
     73              x= ch[x][0];
     74          }else {
     75              k -=(sz[ch[x][0]]+1);
     76              x = ch[x][1];
     77          }
     78          push_down(x);
     79       }
     80       Splay(x,goal);
     81    }
     82    /*void erase(int x ){
     83        int father = pre[x];
     84        int head = 0 , tail = 0 ; 
     85        for()
     86        }*/
     87    void debug(){printf("%d
    ",root);Treaval(root);}
     88    void Treaval(int x) {
     89        if(x) {
     90            Treaval(ch[x][0]);
     91            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d sum = %3lld
    ",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x],sum[x]);
     92            Treaval(ch[x][1]);
     93        }
     94    }
     95    void newnode(int &x,int c)
     96    {
     97       if(top2) x= ss[--top2];
     98       else x = ++ top1;
     99       ch[x][0] = ch[x][1] = pre[x] = 0 ; 
    100       sz[x] = 1;  
    101       
    102       val[x] = sum[x] = c;
    103       add[x] = 0 ; 
    104    }
    105    void push_down(int x){
    106      if(add[x]){
    107         val[x] += add[x];
    108         add[ch[x][0]] += add[x];
    109         add[ch[x][1]] += add[x];
    110         sum[ch[x][0]] += (long long)sz[ch[x][0]] * add[x];
    111         sum[ch[x][1]] += (long long)sz[ch[x][1]] * add[x];
    112         add[x] = 0 ;
    113      }
    114    }
    115    void push_up(int x){
    116       sz[x] = 1 + sz[ch[x][0]] +sz[ch[x][1]];
    117 
    118       sum[x] = add[x] + val[x] + sum[ch[x][0]] + sum[ch[x][1]];
    119    }
    120    void build(int &x,int l ,int r,int f)
    121    {
    122       if(l > r ) return;
    123       int m = (l + r) >> 1; 
    124       newnode(x,num[m]);
    125       build(ch[x][0],l,m-1,x);
    126       build(ch[x][1],m+1,r,x); //这里与线段树不同,因为这个节点本身就含有信息
    127       pre[x] = f;
    128       push_up(x);
    129    }
    130    void init(int n)
    131    {
    132        ch[0][0] = ch[0][1] = pre[0] = sz[0] =0 ; 
    133        add[0] = sum[0] =0 ; 
    134        root = top1 = 0 ; 
    135        newnode(root,-1); //这里注意 root 是从1 开始的
    136        //printf("%d
    ",top1);
    137        
    138        newnode(ch[root][1],-1);
    139        pre[top1] = root ; 
    140        sz[root] = 2;
    141        for(int i = 1;i <= n;i ++)
    142            scanf("%d",&num[i]);
    143        build(keytree,1,n,ch[root][1]);
    144        push_up(ch[root][1]);
    145        push_up(root);
    146    }
    147    void update()
    148    {
    149      int l , r, c; 
    150      scanf("%d %d %d",&l,&r,&c);
    151      Rotateto(l-1,0);
    152      Rotateto(r+1,root);
    153      add[keytree] += c ; 
    154      sum[keytree] += (long long)sz[keytree] * c; 
    155    }
    156    void query()
    157    {
    158      int l , r; 
    159      scanf("%d %d",&l,&r);
    160      Rotateto(l-1,0);
    161      Rotateto(r+1,root);
    162      printf("%lld
    ",sum[keytree]);
    163    }
    164    int num[maxn];
    165    int val[maxn];
    166    int add[maxn];
    167    long long sum[maxn];
    168 }sp; 
    169 int main(){
    170    int n , m ; 
    171    scanf("%d %d",&n,&m);
    172    sp.init(n);
    173    while(m--)
    174    {
    175       char op[10];
    176       scanf("%s",op);
    177       if(op[0] == 'Q')
    178       {
    179         sp.query();
    180       }else {
    181         sp.update();
    182       }
    183       //sp.debug();
    184    }
    185 return 0;
    186 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    前端
    wampserver无法进入到phpmyadmin
    wordpress搭载wampserver上的问题
    电脑不显示网络信号,却能连上网
    读书TODO
    秒杀活动,怎么设计全套技术方案
    淘宝返利知识普及
    如何给变量命名
    一段SQL代码的压缩:从974行到96行,十倍压缩
    nginx一致性hash及应用场景。
  • 原文地址:https://www.cnblogs.com/zyue/p/4080393.html
Copyright © 2011-2022 走看看