zoukankan      html  css  js  c++  java
  • 4358: permu

    4358: permu

    链接

    分析:

      不删除的莫队+可撤销的并查集。

      每次询问先固定左端点到一个块内,然后将这些右端点从小到大排序,然后询问的过程中,右端点不断往右走,左端点可能会撤销,但是移动区间不超过$sqrt n$个,用带撤销的并查集维护。

      复杂度$O(n sqrt n log n)$

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    #include<bitset>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 50005;
    int bel[N], a[N], ans[N], fa[N], dep[N], B, Top, Mx, n;
    bool vis[N];
    struct Que{ int l, r, id; } ; 
    struct Node{ int x, d; } sk[N << 1]; // N * 2 !!! 
    bool operator < (const Que &A,const Que &B) { return A.r < B.r; }
    vector< Que > q[N];
    
    int solve1(int x,int y) {
        if (x == y) return 1;
        vector<int>vec;
        for (int i = x; i <= y; ++i) vec.push_back(a[i]);
        sort(vec.begin(), vec.end());
        int res = 1, now = 1;
        for (int i = 1; i < (int)vec.size(); ++i) 
            vec[i] == vec[i - 1] + 1 ? now ++ : now = 1, res = max(res, now); // !!!
        return res;
    }
    int find(int x) {
        return x == fa[x] ? x : find(fa[x]);
    }
    void Union(int x,int y) {
        x = find(x), y = find(y);
        if (x == y) return ;
        if (dep[x] < dep[y]) swap(x, y);
        Mx = max(Mx, dep[x] + dep[y]);
        fa[y] = x;
        sk[++Top] = (Node){x, dep[x]};
        sk[++Top] = (Node){y, dep[y]};
        dep[x] += dep[y];
    }
    void add(int x) {
        vis[x] = 1;
        if (vis[x - 1]) Union(x - 1, x);
        if (vis[x + 1]) Union(x, x + 1);
    }
    void solve(int now,vector<Que> &vec) {
        Top = 0, Mx = 1;
        int pos = min(N, now * B) + 1, lastpos, lastmx, L = pos, R = pos - 1;
        for (int i = 0; i <= n; ++i) fa[i] = i, dep[i] = 1, vis[i] = 0;
        for (int i = 0; i < (int)vec.size(); ++i) {
            Que v = vec[i];
            while (R < v.r) add(a[++R]);
            lastmx = Mx, lastpos = Top;
            while (L > v.l) add(a[--L]);
            ans[v.id] = Mx;
            Mx= lastmx;
            while (Top > lastpos) fa[sk[Top].x] = sk[Top].x, dep[sk[Top].x] = sk[Top].d, Top --;
            while (L < pos) vis[a[L ++]] = 0;
        }
    }
    int main() {
        n = read();int m = read(); B = sqrt(n);
        for (int i = 1; i <= n; ++i) a[i] = read(), bel[i] = (i - 1) / B + 1;
        for (int i = 1; i <= m; ++i) {
            int x = read(), y = read();
            if (bel[x] == bel[y]) ans[i] = solve1(x, y);
            else q[bel[x]].push_back((Que){x, y, i}); 
        }
        for (int i = 1; i <= bel[n]; ++i) sort(q[i].begin(), q[i].end()), solve(i, q[i]);
        for (int i = 1; i <= m; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    下载ts文件
    gradle plugins/repos/wrapper/tools 国内快速同步下载镜像
    两种方法教你绕过 TPM 2.0 安装 Win11,老电脑也能用 Win 11 了
    波兰极客用一张软盘运行Linux系统,用的还是最新内核
    ARM汇编编程基础
    String、String[]、ArrayList<String>之间的转换
    数据结构资源视频地址
    Zircon初体验-编译运行
    StarUML使用说明-指导手册
    华为RDPM项目管理方法
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10630605.html
Copyright © 2011-2022 走看看