zoukankan      html  css  js  c++  java
  • CF817F MEX Queries

    题意

    维护一个(01)串,一开始全部都是(0)
    (3)种操作
    (1.)把一个区间都变为(1)
    (2.)把一个区间都变为(0)
    (3.)把一个区间的所有数字翻转过来
    每次操作完成之后询问区间最小的(0)的位置
    (l,r<=10^{18})

    Sol

    直接上线段树,如果这个区间左边是满的就去右边,否则去左边
    动态开点,加上(lazy)
    但这样会爆空间

    所以把区间离散化
    注意要离散(1)(l)(r)(l+1)(r+1)
    这些都可能会出现答案

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(4e5 + 5);
    
    IL ll Input(){
        RG ll x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, len, opt[_];
    ll ql[_], qr[_], o[_];
    struct Segment{
        int sum, rev, tag;
    } T[_ << 2];
    
    IL void Adjust1(RG int x, RG int l, RG int r, RG int v){
        T[x].rev = 0, T[x].tag = v--;
        T[x].sum = v * (r - l + 1);
    }
    
    IL void Adjust2(RG int x, RG int l, RG int r){
        T[x].sum = r - l + 1 - T[x].sum;
        T[x].rev ^= 1;
    }
    
    IL void Pushdown(RG int x, RG int l, RG int r){
        RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
        if(T[x].tag){
            Adjust1(ls, l, mid, T[x].tag);
            Adjust1(rs, mid + 1, r, T[x].tag);
            T[x].tag = 0;
        }
        if(T[x].rev){
            Adjust2(ls, l, mid);
            Adjust2(rs, mid + 1, r);
            T[x].rev = 0;
        }
    }
    
    IL void Modify(RG int x, RG int l, RG int r, RG int L, RG int R, RG int v){
        if(L <= l && R >= r){
            Adjust1(x, l, r, v);
            return;
        }
        Pushdown(x, l, r);
        RG int mid = (l + r) >> 1;
        if(L <= mid) Modify(x << 1, l, mid, L, R, v);
        if(R > mid) Modify(x << 1 | 1, mid + 1, r, L, R, v);
        T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum;
    }
    
    IL void Reverse(RG int x, RG int l, RG int r, RG int L, RG int R){
        if(L <= l && R >= r){
            Adjust2(x, l, r);
            return;
        }
        Pushdown(x, l, r);
        RG int mid = (l + r) >> 1;
        if(L <= mid) Reverse(x << 1, l, mid, L, R);
        if(R > mid) Reverse(x << 1 | 1, mid + 1, r, L, R);
        T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum;
    }
    
    IL int Query(RG int x, RG int l, RG int r){
        if(l == r) return l;
        Pushdown(x, l, r);
        RG int mid = (l + r) >> 1, ans;
        if(T[x << 1].sum != mid - l + 1) ans = Query(x << 1, l, mid);
        else ans = Query(x << 1 | 1, mid + 1, r);
        T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum;
        return ans;
    }
    
    int main(RG int argc, RG char *argv[]){
        n = Input(), o[++len] = 1;
        for(RG int i = 1; i <= n; ++i){
            opt[i] = Input(), ql[i] = Input(), qr[i] = Input();
            o[++len] = ql[i], o[++len] = qr[i];
            o[++len] = ql[i] + 1, o[++len] = qr[i] + 1;
        }
        sort(o + 1, o + len + 1), len = unique(o + 1, o + len + 1) - o - 1;
        for(RG int i = 1; i <= n; ++i){
        	ql[i] = lower_bound(o + 1, o + len + 1, ql[i]) - o;
        	qr[i] = lower_bound(o + 1, o + len + 1, qr[i]) - o;
        	if(opt[i] == 1) Modify(1, 1, len, ql[i], qr[i], 2);
        	else if(opt[i] == 2) Modify(1, 1, len, ql[i], qr[i], 1);
        	else Reverse(1, 1, len, ql[i], qr[i]);
        	printf("%lld
    ", o[Query(1, 1, len)]);
        }
        return 0;
    }
    
    
  • 相关阅读:
    国外可用的谷歌地图(可根据地址搜索经纬度)
    后台css框架(自用)
    DBHelp类sql分页(自用笔记)
    定制C++高效安全的运行时动态类型转换
    C++11右值引用和std::move语句实例解析
    浏览器内核-Webkit
    获取股票历史数据和当前数据的API
    从浏览器启动应用程序
    一个实时获取股票数据的安卓应用程序
    C++数据类型总结
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8619821.html
Copyright © 2011-2022 走看看