BZOJ4358: permu(帶撤銷並查集 不刪除莫隊)
阿新 • • 發佈:2019-02-01
++ space freopen class c++ push begin lock con
題意
題目鏈接
Sol
感覺自己已經老的爬不動了。。
想了一會兒,大概用個不刪除莫隊+帶撤銷並查集就能搞了吧,\(n \sqrt{n} logn\)應該卡的過去
不過不刪除莫隊咋寫來著?。。。。跑去學。。
帶撤銷並查集咋寫來著?。。。。跑去學。。。
發現自己的帶撤銷並查集是錯的,,自己yy著調了1h終於過了大數據。。
#include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL long long #define Fin(x) {freopen(#x".in","r",stdin);} #define Fout(x) {freopen(#x".out","w",stdout);} #define pb(x) push_back(x) using namespace std; const int mod = 1e9 + 7; const int MAXN = 1e6 + 10; template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;} template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;} template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;} template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);} template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;} template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;} template <typename A> inline void debug(A a){cout << a << '\n';} template <typename A> inline LL sqr(A x){return 1ll * x * x;} inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, a[MAXN], belong[MAXN], block, ans[MAXN], cnt, fa[MAXN]; struct Q { int l, r, id; bool operator < (const Q &rhs) const{ return r < rhs.r; } }; vector<Q> q[MAXN]; int SolveBlock(int x, int y) { if(x == y) return 1; vector<int> v; for(int i = x; i <= y; i++) v.pb(a[i]); sort(v.begin(), v.end()); int res = 1, now = 1; for(int i = 1; i < v.size(); i++) now = (v[i] == v[i - 1] + 1 ? now + 1 : 1), chmax(res, now); return res; } int inder[MAXN], Top, ha[MAXN], cur, mx; struct Node { int x, deg; }S[MAXN]; int find(int x) { return fa[x] == x ? x : find(fa[x]); } void unionn(int x, int y) { x = find(x); y = find(y); if(x == y) return; if(inder[x] < inder[y]) swap(x, y); chmax(mx, inder[x] + inder[y]); fa[y] = x; S[++Top] = (Node) {y, inder[y]}; S[++Top] = (Node) {x, inder[x]};//tag inder[x] += inder[y]; } void Delet(int cur) { while(Top > cur) { Node pre = S[Top--]; fa[pre.x] = pre.x; inder[pre.x] = pre.deg; } } void Add(int x) { ha[x] = 1; if(ha[x - 1]) unionn(x - 1, x); if(ha[x + 1]) unionn(x, x + 1); } void solve(int i, vector<Q> &v) { memset(ha, 0, sizeof(ha)); Top = 0; int R = min(N, i * block) + 1; int ql = R, qr = ql - 1;//tag cur = 0, mx = 1; for(int i = 1; i <= N; i++) fa[i] = i, inder[i] = 1; for(int i = 0; i < v.size(); i++) { Q x = v[i]; while(qr < x.r) Add(a[++qr]); cur = mx; int pre = Top; while(ql > x.l) Add(a[--ql]); ans[x.id] = mx; mx = cur; Delet(pre); while(ql < R) ha[a[ql++]] = 0; } } signed main() { int mx = 0; N = read(); M = read(); block = sqrt(N); for(int i = 1; i <= N; i++) a[i] = read(), belong[i] = (i - 1) / block + 1, chmax(mx, belong[i]); for(int i = 1; i <= M; i++) { int x = read(), y = read(); if(belong[x] == belong[y]) ans[i] = SolveBlock(x, y); else q[belong[x]].push_back({x, y, i}); } for(int i = 1; i <= mx; i++) sort(q[i].begin(), q[i].end()), solve(i, q[i]); for(int i = 1; i <= M; i++) printf("%d\n", ans[i]); return 0; } /* 8 3 3 1 7 2 4 5 8 6 1 6 1 3 2 4 */
BZOJ4358: permu(帶撤銷並查集 不刪除莫隊)