zoukankan      html  css  js  c++  java
  • P4137 Rmq Problem / mex

    链接

    https://www.luogu.org/problemnew/show/P4137

    思路

    做了好几次,每次都得想一会,再记录一下
    可持久化权值线段树
    区间出现存最小的下标
    然后线段树上二分
    如果左边min>L
    那就去右边
    因为左边都被【L,R】占满了
    虽然比卡常的莫队慢好多(700ms和1000ms)
    但是理论上快哇

    线段树

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    inline int read() {
        int x = 0, f = 1; char s = getchar();
        for(; s > '9' || s < '0'; s = getchar()) if(s == '-') f = -1;
        for(; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
        return x * f;
    }
    int n, m, a[N], rt[N];
    namespace seg_tree {
        #define ls e[rt].ch[0]
        #define rs e[rt].ch[1]
        struct node {int ch[2],mex;}e[N*31];
        int cnt;
        void modify(int &rt, int old, int l, int r, int L) {
            rt = ++cnt;
            e[rt] = e[old];
            if(l == r) {
                e[rt].mex = L; 
                return;
            }
            int mid = (l + r) >> 1;
            if(a[L] <= mid) modify(ls, e[old].ch[0], l, mid, L);
            else modify(rs, e[old].ch[1], mid + 1, r, L);
            e[rt].mex = min(e[ls].mex ,e[rs].mex);
        }
        int query(int rt, int l, int r, int L) {
            if(l == r) return l;
            int mid = (l + r) >> 1;
            if(e[ls].mex >= L) return query(rs, mid + 1, r, L);
            else return query(ls, l, mid, L);
        }
    }
    int main() {    
        n = read(), m = read();
        for (int i = 1; i <= n; ++i) a[i] = min(read(), 200000);
        for (int i = 1; i <= n; ++i) {
            seg_tree::modify(rt[i], rt[i-1], 0, 200000, i);
        }
        for (int i = 1; i <= m; ++i) {
            int x = read(), y = read();
            printf("%d
    ", seg_tree::query(rt[y], 0, 200000, x));
        }
        return 0;
    }
    

    莫队

    // luogu-judger-enable-o2
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #define maxn 301001
    using namespace std;
    int n,m,now;
    int a[maxn];
    int belong[maxn];
    int vis[maxn];
    int ma;
    struct node {
        int l,r,id;
    } q[maxn];
    int ans[maxn];
    inline int read() {
        int x=0,f=1;char s=getchar();
        while('0'>s||s>'9') {if(s=='-') f=-1;s=getchar();}
        while('0'<=s&&s<='9') {x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    inline bool cmp(node a,node b) {
        return belong[a.l]==belong[b.l] ? belong[a.l]&1 ? a.r<b.r : a.r>b.r : belong[a.l]<belong[b.l];
    }
    inline void add(int x) {
        ++vis[x];
        if(now < x) return;
        if(now==x&&vis[x]==1) {
            for(int i=now+1; i<n; ++i) {
                if(!vis[i])	{
                    now=i;
                    return;
                }
            }
        }
    }
    inline void delet(int x) {
        --vis[x];
        if(now < x) return;
        if(now > x) {
            if(!vis[x]) {
                now=x;
            }
        }
    }
    int main() {
        
        n=read();
        m=read();
        int k=n/sqrt(m);
        for(int i=1; i<=n; ++i) {
            a[i]=read();
            if(a[i] > n)
                a[i]=n+1;
        }	
        for(int i=1; i<=n; ++i)
            belong[i]=(i-1)/k+1;
        for(int i=1; i<=m; ++i)
        {
            q[i].l=read();
            q[i].r=read();
            q[i].id=i;	
        }
        sort(q+1,q+1+m,cmp);
        int l=1,r=0;
        for(int i=1; i<=m; ++i) {
            while(l > q[i].l) add(a[--l]);
            while(l < q[i].l) delet(a[l++]);
            while(r < q[i].r) add(a[++r]);
            while(r > q[i].r) delet(a[r--]);
            ans[q[i].id]=now;
        }
        for(int i=1; i<=m; ++i)
            printf("%d
    ",ans[i]);
        return 0;
    }
    
    
  • 相关阅读:
    Qt初始化窗口大小
    Ignatius's puzzle(数学)
    无法定位程序输入点_Z5qFreePv于动态链接库QtCore4.dll
    Harmonic Number(打表法)
    Codeforces Round #170 (Div. 2) C. Learning Languages(并查集)
    Codeforces Round #174 (Div. 2) B. Cows and Poker Game(简单)
    Codeforces Round #175 (Div. 2) B. Find Marble(简单模拟)
    错误:no matching function for call to 'Ui_***::retranslateUi()'
    最大流EK算法模板(BFS实现)
    Shaking Your Cellphone(并查集)
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10393798.html
Copyright © 2011-2022 走看看