• BZOJ4129: Haruna’s Breakfast


    http://www.lydsy.com/JudgeOnline/problem.php?id=4129

      树上带修改求mex,树上带修改莫队即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=50015,maxe=100015,maxm=50015,maxb=255,maxk=20;
    int n,m,ask,tim,a[maxn];
    struct Tmodify{int x,v;}M[maxm];
    struct Tquery{int idx,u,v,t;}Q[maxm];
    int tot,now[maxn],pre[maxe],son[maxe];
    void connect(int u,int v){pre[++tot]=now[u];now[u]=tot;son[tot]=v;}
    void init(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i) scanf("%d",&a[i]);
        for (int u,v,i=1;i<=n-1;++i){
            scanf("%d%d",&u,&v);
            connect(u,v);connect(v,u);
        }
        for (int t,u,v,i=1;i<=m;++i){
            scanf("%d%d%d",&t,&u,&v);
            switch (t){
                case 0:M[++tim]=(Tmodify){u,v};break;
                case 1:Q[++ask]=(Tquery){ask,u,v,tim};break;
            }
        }
    }
    int dep[maxn],anc[maxn][maxk];
    void get_anc(int u,int f){
        anc[u][0]=f;dep[u]=dep[f]+1;
        for (int k=1;k<maxk;++k) anc[u][k]=anc[anc[u][k-1]][k-1];
        for (int p=now[u];p;p=pre[p]) if (son[p]!=f) get_anc(son[p],u);
    }
    int siz1,top,cnt,stk[maxn],bel[maxn];
    void get_block(int u,int f){
        for (int bot=top,p=now[u];p;p=pre[p]){
            if (son[p]==f) continue;get_block(son[p],u);
            if (top-bot>=siz1) for (++cnt;top!=bot;bel[stk[top--]]=cnt);
        }
        stk[++top]=u;
    }
    bool cmp(Tquery a,Tquery b){
        if (bel[a.u]!=bel[b.u]) return bel[a.u]<bel[b.u];
        else if (bel[a.v]!=bel[b.v]) return bel[a.v]<bel[b.v];
        else return a.t<b.t;
    }
    void prepare(){
        siz1=pow(n,0.67);
        get_anc(1,0);get_block(1,0);
        while (top) bel[stk[top--]]=cnt;
        for (int i=1;i<=ask;++i) if (bel[Q[i].u]>bel[Q[i].v]) swap(Q[i].u,Q[i].v);
        sort(Q+1,Q+ask+1,cmp);
    }
    bool exist[maxn];
    int num,siz2,ans[maxm],bl[maxb],br[maxb],have[maxb],idx[maxn],sum[maxn];
    void xor_node(int u){
        if (exist[u]){if (a[u]<=n) if (!--sum[a[u]]) --have[idx[a[u]]];}
        else if (a[u]<=n) if (!sum[a[u]]++) ++have[idx[a[u]]];
        exist[u]^=1;
    }
    void xor_path(int u,int v){
        if (dep[u]<dep[v]) swap(u,v);
        while (dep[u]!=dep[v]){xor_node(u);u=anc[u][0];}
        while (u!=v){xor_node(u);xor_node(v);u=anc[u][0];v=anc[v][0];}
    }
    void modify(int t){
        int x=M[t].x,v=M[t].v;
        if (exist[x]){
            if (a[x]<=n) if (!--sum[a[x]]) --have[idx[a[x]]];
            if (v<=n) if (!sum[v]++) ++have[idx[v]];
        }
        swap(M[t].v,a[x]);
    }
    void move_time(int ever,int now){
        for (int i=ever+1;i<=now;++i) modify(i);
        for (int i=ever;i>=now+1;--i) modify(i);
    }
    int lca(int u,int v){
        if (dep[u]<dep[v]) swap(u,v);
        for (int h=dep[u]-dep[v],i=0;h;h>>=1,++i) if (h&1) u=anc[u][i];
        for (int k=maxk-1;k>=0;--k) if (anc[u][k]!=anc[v][k]){u=anc[u][k];v=anc[v][k];}
        return u==v?u:anc[u][0];
    }
    int get_ans(){
        int pos,res;
        for (pos=0;have[pos]==siz2;++pos);
        for (res=bl[pos];sum[res];++res);
        return res;
    }
    void solve(int k){
        xor_path(Q[k-1].u,Q[k].u);
        xor_path(Q[k-1].v,Q[k].v);
        move_time(Q[k-1].t,Q[k].t);
        int x=lca(Q[k].u,Q[k].v);
        xor_node(x);ans[Q[k].idx]=get_ans();xor_node(x);
    }
    void work(){
        prepare();siz2=sqrt(n);
        for (int j,i=0;i<=n;i=j,++num){
            for (j=i;j-i+1<=siz2&&j<=n;++j) idx[j]=num;
            bl[num]=i;br[num]=j-1;
        }
        for (int i=1;i<=ask;++i) solve(i);
        for (int i=1;i<=ask;++i) printf("%d
    ",ans[i]);
    }
    int main(){
        init();
        work();
        return 0;
    }
    my code
  • 相关阅读:
    logstash 配置 logstash-forwarder (前名称:lumberjack)
    你不知道的if,else
    css样式
    表格 表单
    学习第一天练习
    唯有作茧自缚,方可破茧成蝶
    第一周复习二 (CSS样式表及其属性)
    第一周复习一 ( HTML表单form)
    汉企第一天小记
    C语言 -- register关键字
  • 原文地址:https://www.cnblogs.com/iamCYY/p/4720029.html
Copyright © 2020-2023  润新知