• CF1080F Katya and Segments Sets


    题目链接:洛谷

    题目描述:【看翻译】


    这种强制在线的方法可真是奇妙。

    主席树可真是奇妙。

    我们用主席树的版本维护$xleq l$的限制,用线段树维护$[a,b]$的限制,用节点的值来维护$rleq y$的限制。

    详细地说,就是先将线段排序($l$为第一关键字,$r$为第二关键字),然后倒序所属集合作为位置,右端点作为值插入主席树。

    主席树的第$i$个版本维护的是排序后,后面$k-i+1$个线段的线段树。

    因为它要求集合里面有一个满足就可以,所以同一个位置的右端点取最小值

    因为它要求$[a,b]$的集合都要满足,所以线段树维护区间最大值

    每次查询的时候,找到左端点$geq x$的最靠前的线段,设为第$i$个,则在第$i$个版本中,看$[a,b]$的最大值是否$leq y$,如果是就是yes,否则就是no。

     1 #include<bits/stdc++.h>
     2 #define Rint register int
     3 using namespace std;
     4 const int N = 300003, INF = 0x3f3f3f3f;
     5 struct Seg {
     6     int l, r, p;
     7     inline bool operator < (const Seg &o) const {return l < o.l || l == o.l && r < o.r;}
     8 } a[N];
     9 int n, m, k, cnt, root[N], seg[N << 5], ls[N << 5], rs[N << 5];
    10 inline void pushup(int x){
    11     seg[x] = max(seg[ls[x]], seg[rs[x]]);
    12 }
    13 inline void build(int &x, int L, int R){
    14     seg[x = ++ cnt] = INF;
    15     if(L == R) return;
    16     int mid = L + R >> 1;
    17     build(ls[x], L, mid);
    18     build(rs[x], mid + 1, R);
    19 }
    20 inline void change(int &nx, int ox, int L, int R, int pos, int val){
    21     seg[nx = ++ cnt] = seg[ox];
    22     ls[nx] = ls[ox]; rs[nx] = rs[ox];
    23     if(L == R){
    24         seg[nx] = min(seg[nx], val);
    25         return;
    26     }
    27     int mid = L + R >> 1;
    28     if(pos <= mid) change(ls[nx], ls[ox], L, mid, pos, val);
    29     else change(rs[nx], rs[ox], mid + 1, R, pos, val);
    30     pushup(nx);
    31 }
    32 inline int query(int x, int L, int R, int l, int r){
    33     if(l <= L && R <= r) return seg[x];
    34     int mid = L + R >> 1, ans = 0;
    35     if(l <= mid) ans = max(ans, query(ls[x], L, mid, l, r));
    36     if(mid < r) ans = max(ans, query(rs[x], mid + 1, R, l, r));
    37     return ans;
    38 }
    39 int main(){
    40     scanf("%d%d%d", &n, &m, &k);
    41     for(Rint i = 1;i <= k;i ++)
    42         scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].p);
    43     sort(a + 1, a + k + 1);
    44     build(root[k + 1], 1, n);
    45     for(Rint i = k;i;i --)
    46         change(root[i], root[i + 1], 1, n, a[i].p, a[i].r);
    47     a[k + 1].l = INF; 
    48     while(m --){
    49         int A, B, X, Y;
    50         scanf("%d%d%d%d", &A, &B, &X, &Y);
    51         int ans = -1, mid, left = 1, right = k + 1;
    52         while(left <= right){
    53             mid = left + right >> 1;
    54             if(a[mid].l >= X) ans = mid, right = mid - 1;
    55             else left = mid + 1;
    56         }
    57         puts(query(root[ans], 1, n, A, B) <= Y ? "yes" : "no");
    58         fflush(stdout);
    59     }
    60 }
    View Code
  • 相关阅读:
    python笔记1
    git笔记
    手撸一个简陋直播系统
    spring-boot学习笔记1
    设计模式1--简单工厂模式
    网联:第一章:浏览器生成消息
    php线上预览日志--4.websocket客户端
    php线上预览日志--3.websocket服务部署
    php线上预览日志--2.谷歌插件开发
    php线上预览日志--1.概述
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/ntfakgdoi.html
Copyright © 2020-2023  润新知