[2020杭电多校第一场]1006 Finding a Mex(分块)

考虑分块,大于块数的动态开点权值线段树,小于的话暴力修改。

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define ll long long
#define PB push_back
#define endl '
'
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) (x & (-x))
#define rep(i, a, b) for(int i = a ; i <= b ; ++ i)
#define per(i, a, b) for(int i = b ; i >= a ; -- i)
#define clr(a, b) memset(a, b, sizeof(a))
#define in insert
#define random(x) (rand()%x)
#define PII(x, y) make_pair(x, y)
#define fi first
#define se second
#define pi acos(-1)
#define re register
//std::ios::sync_with_stdio(false);
using namespace std;
const int maxn = 1e6 + 50;
const int N = 1e5 + 10;
const int M = N * 20;
const ll mod = 1e9 + 9;
int T, bk, cnt, n, m;
int w[N], x[N], y[N], du[N], rt[N], vis[N], ls[M], rs[M], sum[M], num[M];
vector<int> g[N], G[N];
#define mid ((l + r) >> 1)
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
    int x=0,f=1; char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
    return x*f;
}
inline void update(int &p, int l, int r, int x, int y){
    if(!p) {p = ++ cnt; ls[p] = rs[p] = sum[p] = num[p] = 0;}
    //cout << p <<endl;
    if(l == r) {sum[p] += y; num[p] = (sum[p]>0?1:0); return;}
    if(x <= mid) update(ls[p], l, mid, x, y);
    else update(rs[p], mid + 1, r, x, y);
    sum[p] = sum[ls[p]] + sum[rs[p]];
    num[p] = num[ls[p]] + num[rs[p]];
}
inline int query(int p, int l, int r){
    if(l == r) return l;
    if(num[ls[p]] >= mid - l + 1) return query(rs[p], mid + 1, r);
    else return query(ls[p], l, mid);
}
void upd(int x, int y){
    for(int v : G[x]){
        update(rt[v], 0, 1e9, w[x], -1); update(rt[v], 0, 1e9, y, 1);
    }
    w[x] = y;
}
int cal(int x){
    if(vis[x]) return query(rt[x], 0, 1e9);
    vector<int> t;
    for(int v : g[x]) t.PB(w[v]);
    sort(t.begin(), t.end()); t.erase(unique(t.begin(), t.end()), t.end());
    for(int i = 0 ; i < t.size() ; ++ i) if(t[i]!=i) return i;
    return (int)t.size();
}
signed main(){
    freopen("C://std/a.in","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
    freopen("C://std/b.txt","w",stdout);
    int q, op, u, v;
    T = read();
    while(T --){
        n = read(); m = read();
        bk=sqrt(log2(n+m)*(n+m)); cnt = 0;
        rep(i, 1, n) w[i]=read(), du[i]=rt[i]=vis[i]=0, g[i].clear(), G[i].clear();
        rep(i, 1, m){
            x[i] = read(); y[i] = read();
            du[y[i]] ++; du[x[i]] ++;
            g[x[i]].PB(y[i]); g[y[i]].PB(x[i]);
        }
        rep(i, 1, n) if(du[i] >= bk) vis[i] = 1;
        rep(i, 1, m){
            if(vis[x[i]]) G[y[i]].PB(x[i]), update(rt[x[i]], 0, 1e9, w[y[i]], 1);
            if(vis[y[i]]) G[x[i]].PB(y[i]), update(rt[y[i]], 0, 1e9, w[x[i]], 1);
        }
        q = read();
        while(q --){
            op = read(); u = read();
            if(op == 1) v = read(), upd(u, v);
            else printf("%d
", cal(u));
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Ketchum/p/13372731.html