zoukankan      html  css  js  c++  java
  • 【题解】Interval [牛客

    题目链接

    题意

    • page15image35065504
    • 注意L可能大于R(应该都注意到了)

    题解

    • 对于固定的左端点或者右端点,不同的值至多只有log个
    • 先把这些值找出来,然后去掉具有包含关系的相同的值
    • 单纯的二维偏序求和无法处理相同的值
    • 那么把相同的值按顺序放在一起 (l1,r1)(l2,r2)...(lp,rp)
    • 那么如果查询包含了(l1,r2)(l2,r3)...(lp-1,rp)这些区间,答案就应该-1
    • 所以设置一些权值为-1的区间,再二维偏序即可

    总结

    对于一般的(离线)二维偏序问题,常常对第一维排序后,用树状数组维护第二维的值。

    而这道题中,需要解决的是强制在线的二维偏序问题,就需要用到主席树处理区间。

    多个根结点rt[i]代表不同的右区间,通过继承上一个根结点的信息,保证了其内部包括的区间的第二维只会是递增的。

    主席树此时等价于n棵线段树,查询操作相当于询问左区间个数之和,时间复杂度是log(n)的。

    代码

    #include <iostream>
    #include <map>
    using namespace std;
    const int N = 1e5 + 5;
    #define mid ((l+r)>>1)
    #define lson tr[o].l, l, mid
    #define rson tr[o].r, mid+1, r
    
    struct node {
       int sum, l, r;
    }tr[N*400];
    int tot = 0, rt[N]; // 空间开32倍RE了
    
    void update(int &o, int l, int r, int i, int v) {
       tr[++tot] = tr[o]; o = tot; tr[o].sum += v; // 继承上一个右区间的信息后,更新点权
       if(l == r) return;
       else if(i <= mid) update(lson, i, v);
       else update(rson, i, v);
    }
    
    int query(int o, int l, int r, int L, int R) {
       if(l > R || r < L) return 0;
       if(L <= l && r <= R) return tr[o].sum;
       return query(lson, L, R) + query(rson, L, R);
    }
    
    int main() {
       int n; scanf("%d", &n);
       map<int, int> pre, his;
       for (int i = 1; i <= n; i++) {
           int x; scanf("%d", &x);
           map<int, int> cur;
           pre[(1<<30)-1] = i; // 考虑当前节点构成区间
           for (auto o : pre) {
               int key = o.first & x;
               cur[key] = max(cur[key], o.second);
          }
           
           rt[i] = rt[i-1]; // 继承上一个右区间的信息
           for (auto o : cur) {
               if(his.count(o.first)) {
                   update(rt[i], 1, n, his[o.first], -1); // 去重
              }
               his[o.first] = o.second;
               update(rt[i], 1, n, o.second, 1);
          }
           
           swap(cur, pre);
      }
       
       int q;
       scanf("%d", &q);
       int last = 0;
       while (q--) {
           int l, r;
           scanf("%d %d", &l, &r);
           l = (l ^ last) % n + 1;
           r = (r ^ last) % n + 1;
           
           if(l > r) swap(l, r);
           last = query(rt[r], 1, n, l, r);
           printf("%d
    ", last);
      }
    }
    
  • 相关阅读:
    Squeeze-and-Attention Networks for Semantic Segmentation
    重装电脑系统(用山寨优盘)
    TensorFlow会话常用的两种方式
    Towards Learning Structure via Consensus for Face Segmentation and Parsing
    什么是feature map(个人理解)
    Fatal error in launcher: Unable to create process using '"d:downloadpython.exe" "D:downloadScriptspip.exe" list': ???????????
    JS :函数
    JS之继承
    原型模式
    面向对象之工厂模式和构造函数模式
  • 原文地址:https://www.cnblogs.com/Waldeinsamkeit/p/13444902.html
Copyright © 2011-2022 走看看