1、题目大意:维护序列,只有区间翻转这个操作

2、分析:splay的经典操作就是实现区间翻转,就是在splay中有一个标记,表示这个区间被翻转了

然后就是记得各种的操作访问某个点时,记得下传,顺便交换一下左右子树的左右子树(我语文不好

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    Node *ch[2];
    int f, v, s;
    int cmp(int x){
        if(x < v) return 0;
        else if(x == v) return -1;
        else return 1;
    }
    int cmp1(int x){
        int k = 1;
        if(ch[0]) k += ch[0] -> s;
        if(x < k) return 0;
        else if(x == k) return -1;
        else if(x > k) return 1;
    }
    void maintain(){
        s = 1;
        if(ch[0]) s += ch[0] -> s;
        if(ch[1]) s += ch[1] -> s;
    }
    void pushdown(){
        if(f == 1){
            if(ch[0] != NULL){
                ch[0] -> f ^= 1;
                swap(ch[0] -> ch[0], ch[0] -> ch[1]);
            }
            if(ch[1] != NULL){
                ch[1] -> f ^= 1;
                swap(ch[1] -> ch[0], ch[1] -> ch[1]);
            }
            f = 0;
        }
    }
};
struct splay_tree{
    Node ft[2000000];
    Node *root;
    int a[200000], tot;
    void rotate(Node* &o, int d){
        Node *k = o -> ch[d ^ 1];
        k -> pushdown();
        o -> ch[d ^ 1] = k -> ch[d];
        k -> ch[d] = o;
        o -> maintain();
        k -> maintain();
        o = k;
    }
    void splay(Node* &o, int k){
        if(!o) return;
        o -> pushdown();
        if(o -> ch[0]) o -> ch[0] -> pushdown();
        if(o -> ch[1]) o -> ch[1] -> pushdown();
        int d = o -> cmp1(k);
        if(d == 1 && o -> ch[0]) k = k - o -> ch[0] -> s - 1;
        else if(d == 1) k --;
        if(d != -1){
            Node* w = o -> ch[d];
            int d2 = w -> cmp1(k);
            int k2 = k;
            if(d2 == 1){
                k2 --;
                if(w -> ch[0]) k2 -= w -> ch[0] -> s;
            }
            if(d2 != -1){
                splay(w -> ch[d2], k2);
                if(d == d2) rotate(o, d ^ 1);
                else rotate(o -> ch[d], d);
            }
            rotate(o, d ^ 1);
        }
        return;
    }
    Node* merge(Node *left, Node *right){
        if(left == NULL) return right;
        if(right == NULL) return left;
        splay(left, left -> s);
        left -> ch[1] = right;
        left -> maintain();
        return left;
    }
    void split(Node* &o, int k, Node* &left, Node* &right){
        if(k == 0){
            left = NULL;
            right = o;
            return;
        }
        splay(o, k);
        left = o;
        right = o -> ch[1];
        left -> ch[1] = NULL;
        left -> maintain();
        return;
    }
    void flip(int l, int r){
        Node *left, *mid, *right;
        split(root, l - 1, left, mid);
        split(mid, r - l + 1, mid, right);
        swap(mid -> ch[0], mid -> ch[1]);
        mid -> f ^= 1;
        root = merge(left, merge(mid, right));
    }
    int value(int l){
        Node *left, *mid, *right;
        split(root, l - 1, left, mid);
        split(mid, 1, mid, right);
        int ret = mid -> v;
        root = merge(left, merge(mid, right));
        return ret;
    }
    void insert(Node* &o, int l, int r){
        if(r < l) return;
        int mid = (l + r) / 2;
        o = &ft[tot]; tot ++;
        o -> ch[0] = o -> ch[1] = NULL;
        o -> v = mid;
        o -> f = 0;
        if(l != r){
            insert(o -> ch[0], l, mid - 1);
            insert(o -> ch[1], mid + 1, r);
        }
        o -> maintain();
        return;
    }
} wt;
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++) wt.a[i] = i;
    wt.insert(wt.root, 1, n);
    for(int i = 1; i <= m; i ++){
        int l, r;
        scanf("%d%d", &l, &r);
        wt.flip(l, r);
    }
    for(int i = 1; i <= n; i ++){
        printf("%d ", wt.value(i));
    }
    return 0;
}

最新文章

  1. java程序实现删除本地文件
  2. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)
  3. hdfs namenode -initializeSharedEdits 和 hdfs namenode -bootstrapStandby
  4. 使用rsyslog+loganalzey收集日志显示客户端ip
  5. MVVM模式应用体会
  6. Google+ 技巧四则
  7. 更新xcode后插件失效问题——不针对特定版本的通用解决方法
  8. Windows与自定义USB HID设备通信说明.
  9. [置顶] Guava学习之Iterators
  10. python基础教程_学习笔记1:序列-1
  11. 二叉树的递归遍历 Tree UVa548
  12. JavaScript验证和数据处理的干货(经典)
  13. 读取InputStream 中的内容
  14. Springboot 中配置文件的优先级和加载顺序
  15. spring重要知识点总结
  16. laravel 在nginx服务器上除了首页其余都是404的问题
  17. 选择排序之python
  18. hibernate注解主键生成策略
  19. 再看javascript执行上下文、变量对象
  20. 人生第一个快速幂的题(HDU - 1097--A hard puzzle )

热门文章

  1. confluence安装
  2. ASP.NET 递归将分类绑定到 TreeView
  3. Ubuntu系统安装(win7双系统)
  4. 利用百度开发者中心的api实现地图及周边的搜索
  5. linux配置IP的方法
  6. datagrid---写后台数据交互
  7. Unreal模型文件调查
  8. iOS监听键盘事件
  9. 硬盘安装win10
  10. redis入侵小结