zoukankan      html  css  js  c++  java
  • [luogu3391][文艺平衡树]

    题目链接

    思路

    splay区间操作的裸题。
    假如要对l-r这段区间操作,那么就先把l-1伸展到根节点,然后把r +1伸展为根的儿子。这样r + 1的左儿子就是要操作的区间了。只要在上面打上标记,以后每次查询的时候pushdown一下。
    然后对于l-1和r+1节点可能不存在,所以可以放两个标兵元素。就是一个极小值一个极大值(合适即可)。
    对于这道题。只要每次修改的时候,按照上面的方法进行伸展。然后打标机即可。打标记的方法就是用0/1来表示当前区间是否被翻转,每次翻转就将标记^1即可。

    代码

    /*
    * @Author: wxyww
    * @Date:   2018-12-09 08:43:41
    * @Last Modified time: 2018-12-09 11:00:52
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<bitset>
    using namespace std;
    #define ls TR[cur].ch[0]
    #define rs TR[cur].ch[1]
    typedef long long ll;
    const int N = 100000 + 100;
    ll read() {
       ll x=0,f=1;char c=getchar();
       while(c<'0'||c>'9') {
          if(c=='-') f=-1;
          c=getchar();
       }
       while(c>='0'&&c<='9') {
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }
    int rt,tot,n,m;
    struct node {
       int val,ch[2],lazy,siz,pre;
    }TR[N];
    void pushup(int cur) {
       TR[cur].siz = TR[ls].siz + TR[rs].siz + 1;
    }
    void pushdown(int cur) {
       if(TR[cur].lazy) {
          TR[ls].lazy ^= 1;
          TR[rs].lazy ^= 1;
          TR[cur].lazy ^= 1;
          swap(ls,rs);
       }
    }
    int build(int l,int r,int father) {
       if(l > r) return 0;
       int cur = (l + r) >> 1;
       TR[cur].val = cur - 1;
       TR[cur].pre = father;
       TR[cur].siz = 1;
       ls = build(l,cur - 1,cur);
       rs = build(cur + 1,r,cur);
       pushup(cur);
       return cur;
    }
    int getwh(int cur) {
       return TR[TR[cur].pre].ch[1] == cur;
    }
    void rotate(int cur) {
        int fa = TR[cur].pre,gr = TR[fa].pre;
        int f = getwh(cur);
        TR[gr].ch[getwh(fa)] = cur;
        TR[cur].pre = gr;
        TR[fa].ch[f] = TR[cur].ch[f ^ 1];
        TR[TR[cur].ch[f ^ 1]].pre = fa;
        TR[fa].pre = cur;
        TR[cur].ch[f ^ 1] = fa;
        pushup(fa);
        pushup(cur);
    }
    void splay(int cur,int to) {
       while(TR[cur].pre != to) {
          if(TR[TR[cur].pre].pre != to) {
             if(getwh(TR[cur].pre) != getwh(cur)) rotate(TR[cur].pre);
             else rotate(cur);
          }
          rotate(cur);
       }
       if(!to) rt = cur;
    }
    int kth(int now) {
       int cur = rt;
       while(cur) {
          pushdown(cur);
          if(now <= TR[ls].siz) cur = ls;
          else if(now > TR[ls].siz + 1) now -= TR[ls].siz + 1,cur = rs;
          else return cur; 
       }
    }
    void work(int l,int r) {
       int k1 = kth(l),k2 = kth(r + 2);
       splay(k1,0);
       splay(k2,k1);
       TR[TR[k2].ch[0]].lazy ^= 1;
       pushdown(TR[k2].ch[0]);
    }
    void print(int cur) {
       if(!cur) return;
       pushdown(cur);
       print(ls);
       if(TR[cur].val != 0 && TR[cur].val != n + 1)
       printf("%d ",TR[cur].val);
       print(rs);
    }
    int main() {
       n = read(),m = read();
       rt = build(1,n + 2,0);
       while(m--) {
          int l = read(),r = read();
          work(l,r);
       }
       print(rt);
       return 0;
    }
    

    一言

    有伤害人的人存在的话,也会有能抚慰伤痕的人

  • 相关阅读:
    一个关于STL list使用 小示例
    c++几个通用工具
    修改pc机的mac地址 以及 mac地址的组成
    win7 下 arp 绑定mac和Ip
    wireshark如何抓取别人电脑的数据包
    WPA破解原理简要——无线网络破解续
    Apache配置代理服务器的方法(2)
    Apache配置代理服务器的方法(1)
    在Linux系统中如何设置APACHE服务器里的后台页面只允许某个IP地址访问
    Apache服务器配置技巧
  • 原文地址:https://www.cnblogs.com/wxyww/p/10090550.html
Copyright © 2011-2022 走看看