zoukankan      html  css  js  c++  java
  • POJ3468 本来是一道线段树

    // 然而博主用 Splay Tree 做的,4000+ ms。。。飘过

      1 #include "cstdio"
      2 using namespace std;
      3 long long in[100010];
      4 const int INF = 1 << 28;
      5 
      6 struct Node {
      7     Node *pre, *ch[2];
      8     long long sz, val;
      9     long long sum, add;
     10 } *null, *root, buf[100010];
     11 int idx;
     12 
     13 Node *usdNode[100010];
     14 int top;
     15 
     16 inline void PushDown(Node *p)
     17 {
     18     if (p == null) {
     19         return ;
     20     }
     21     if(p->add) {
     22         p->sum += p->add * p->sz;
     23         p->val += p->add;
     24         if(p->ch[0] != null) {
     25             p->ch[0]->add += p->add;
     26         }
     27         if(p->ch[1] != null) {
     28             p->ch[1]->add += p->add;
     29         }
     30         p->add = 0;
     31     }
     32 }
     33 
     34 inline void Update(Node *p)
     35 {
     36     if (p == null) {
     37         return ;
     38     }
     39     PushDown(p);
     40     PushDown(p->ch[0]);
     41     PushDown(p->ch[1]);
     42     p->sz = p->ch[0]->sz + p->ch[1]->sz + 1;
     43     p->sum = p->ch[0]->sum + p->ch[1]->sum + p->val;
     44 }
     45 
     46 Node *AddNode(int val)
     47 {
     48     Node *p;
     49     if (top) {
     50         p = usdNode[top];
     51         --top;
     52     } else {
     53         ++idx;
     54         p = &buf[idx];
     55     }
     56     p->pre = p->ch[0] = p->ch[1] = null;
     57     p->sz = 1, p->val = val;
     58 
     59     p->add = 0;
     60     p->sum = val;
     61     return p;
     62 }
     63 
     64 void Init()
     65 {
     66     idx = top = 0;
     67     null = AddNode(-INF);
     68     null->sz = 0;
     69     null->sum = 0;
     70     root = AddNode(-INF);
     71 
     72     root->sum = 0;
     73     Node *p;
     74 
     75     p = AddNode(-INF);
     76     p->sum = 0;
     77 
     78     root->ch[1] = p;
     79     p->pre = root;
     80     Update(root->ch[1]);
     81     Update(root);
     82 }
     83 
     84 void Rotate(Node *p, bool c)
     85 {
     86     Node *f = p->pre;
     87     PushDown(f);
     88     PushDown(p);
     89     f->ch[!c] = p->ch[c];
     90     if (p->ch[c] != null) {
     91         p->ch[c]->pre = f;
     92     }
     93     p->pre = f->pre;
     94     if (f->pre != null) {
     95         if (f->pre->ch[0] == f) {
     96             f->pre->ch[0] = p;
     97         } else {
     98             f->pre->ch[1] = p;
     99         }
    100     }
    101     p->ch[c] = f;
    102     f->pre = p;
    103     if (f == root) {
    104         root = p;
    105     }
    106     Update(f);
    107 }
    108 
    109 void Splay(Node *p, Node *tf)
    110 {
    111     Node *f, *ff;
    112     PushDown(p);
    113     while (p->pre != tf) {
    114         f = p->pre, ff = f->pre;
    115         if (ff == tf) {
    116             Rotate(p, p->pre->ch[0] == p);
    117         } else {
    118             if (ff->ch[0] == f) {
    119                 if (f->ch[0] == p) {
    120                     Rotate(f, 1);
    121                     Rotate(p, 1);
    122                 } else {
    123                     Rotate(p, 0);
    124                     Rotate(p, 1);
    125                 }
    126             } else {
    127                 if (f->ch[1] == p) {
    128                     Rotate(f, 0);
    129                     Rotate(p, 0);
    130                 } else {
    131                     Rotate(p, 1);
    132                     Rotate(p, 0);
    133                 }
    134             }
    135         }
    136         Update(p);
    137     }
    138 }
    139 
    140 Node *Build(int l, int r)
    141 {
    142     if (l > r) {
    143         return null;
    144     }
    145     int mid = (l + r) >> 1;
    146     Node *p = AddNode(in[mid]);
    147     p->ch[0] = Build(l, mid - 1);
    148     if (p->ch[0] != null) {
    149         p->ch[0]->pre = p;
    150     }
    151     p->ch[1] = Build(mid + 1, r);
    152     if (p->ch[1] != null) {
    153         p->ch[1]->pre = p;
    154     }
    155     Update(p);
    156     return p;
    157 }
    158 
    159 Node *Select(int kth)
    160 {
    161     int tmp;
    162     Node *p = root;
    163     while (1) {
    164         PushDown(p);
    165         tmp = p->ch[0]->sz;
    166         if (tmp + 1 == kth) {
    167             break;
    168         }
    169         if (kth <= tmp) {
    170             p = p->ch[0];
    171         } else {
    172             kth -= tmp + 1;
    173             p = p->ch[1];
    174         }
    175     }
    176     return p;
    177 }
    178 
    179 void SegAdd(int pos, int tot, long long delte)
    180 {
    181     Splay(Select(pos - 1), null);
    182     Splay(Select(pos + tot), root);
    183     if (root->ch[1]->ch[0] != null) {
    184         root->ch[1]->ch[0]->add += delte;
    185         Splay(root->ch[1]->ch[0], null);
    186     }
    187 }
    188 
    189 void GetSum(int pos, int tot)
    190 {
    191     Splay(Select(pos - 1), null);
    192     Splay(Select(pos + tot), root);
    193     printf("%lld
    ",root->ch[1]->ch[0]->sum);
    194 }
    195 
    196 int N, Q;
    197 char cmd[10];
    198 
    199 int main()
    200 {
    201     int i;
    202     scanf("%d%d", &N, &Q);
    203     Init();
    204     for(i = 1; i <= N; ++i) {
    205         scanf("%lld", &in[i]);
    206     }
    207     Node *tRoot = Build(1, N);
    208     root->ch[1]->ch[0] = tRoot;
    209     tRoot->pre = root->ch[1];
    210     Update(root->ch[1]);
    211     Update(root);
    212 
    213     int l, r;
    214     long long c;
    215     while(Q--) {
    216         scanf("%s", cmd);
    217         switch(cmd[0]) {
    218         case 'Q':
    219             scanf("%d%d", &l, &r);
    220             GetSum(l + 1, r - l + 1);
    221             break;
    222         case 'C':
    223             scanf("%d%d%lld", &l, &r, &c);
    224             SegAdd(l + 1, r - l + 1, c);
    225         }
    226     }
    227 }
  • 相关阅读:
    安装vs2012后sql2008配置管理出错
    教你台式机如何接双显示器
    去除Office 2010的右键“共享文件夹同步”菜单
    内网的用户不能用外网IP访问内网
    VMware Workstation 8的简明使用教程
    EntityFramework4.0中遇到New transaction is not allowed because there are other threads running in the session
    几条软件开发心得
    .net各版本反射多种方法介绍
    .net4.0下的Lazy<T>类型简单应用
    使用DebugView小工具调试已部署的.net程序
  • 原文地址:https://www.cnblogs.com/AC-Phoenix/p/4674992.html
Copyright © 2011-2022 走看看