BZOJ 4129 Haruna’s Breakfast

来源:互联网 发布:单片机红外接收原理 编辑:程序博客网 时间:2024/05/16 15:36

感觉关于树的不管是啥都200+行。。。一口老血。。。

首先树上分个块(大概就是BZOJ1086王室联邦的套路,此处应有链接,可惜这道题还在坑里233),然后每次暴力移动点,尤其是关于lca的处理需要很注意(见下图):


(假装有图)


然后这里需要求mex值。对于mex值暴力当然会TLE,于是需要分块。将n个数分成sqrt(n),查询时从头查看哪个块数未满,然后在块中暴力寻找数,复杂度O(sqrt n)。


千万要记得,当一个数修改为大于n时,此数必然不会成为mex数,可以直接跳过,数组开到maxn即可,以免造成MLE。


#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm> using namespace std; const int maxn=200005; struct edge{    int to,next;}e[maxn<<1];struct query{    int l,r,id,t;}q[maxn];struct change{    int pre,sub,pos;}c[maxn]; int n,m,cnt,tot,numblock;int bcnt,block;int head[maxn];int s[maxn],last[maxn],ans[maxn];int size[maxn],belong[maxn],depth[maxn];bool inpath[maxn];int num[maxn],bnum[maxn];int ff[maxn][22]; bool cmp(query a,query b){    return belong[a.l]<belong[b.l]||(belong[a.l]==belong[b.l]&&belong[a.r]<belong[b.r])            ||(belong[a.l]==belong[b.l]&&belong[a.r]==belong[b.r]&&a.t<b.t);}void insert(int a,int b){    static int ecnt=0;    e[++ecnt].to=b;e[ecnt].next=head[a];head[a]=ecnt;}void dfs(int x,int fa){    static int stack[maxn],top,rear;    int bottom=stack[rear];    stack[++rear]=x;    size[x]=1;    ff[x][0]=fa;    for(int i=head[x];i;i=e[i].next)        if(e[i].to!=fa)    {        depth[e[i].to]=depth[x]+1;        dfs(e[i].to,x);        size[x]+=size[e[i].to];        if(size[x]>=block)        {            ++bcnt;            while(stack[rear]!=bottom)            {                int t=stack[rear--];                belong[t]=bcnt;            }        }    }}void update(int x){    inpath[x]=true;    if(s[x]>n)return;//    if(!num[s[x]])bnum[s[x]/numblock]++;    num[s[x]]++;}void downdate(int x){    inpath[x]=false;    if(s[x]>n)return;//    if(num[s[x]]==1)bnum[s[x]/numblock]--;    num[s[x]]--;}void xorpath(int x,int y){    if(depth[x]<depth[y])swap(x,y);    while(depth[x]>depth[y])    {        if(inpath[x])downdate(x);        else update(x);        x=ff[x][0];    }    while(x!=y)    {        if(inpath[x])downdate(x);        else update(x);        x=ff[x][0];        if(inpath[y])downdate(y);        else update(y);        y=ff[y][0];    }}int lca(int x,int y){    if(depth[x]<depth[y])swap(x,y);    int pos=0,delta=depth[x]-depth[y];    while(delta)    {        if(delta&1)x=ff[x][pos];        pos++;        delta>>=1;    }    if(x==y)return x;    for(int i=20;i>=0;i--)        if(ff[x][i]!=ff[y][i])            x=ff[x][i],y=ff[y][i];    return ff[x][0];}void st_chart(){    for(int i=1;i<=n;i++)        for(int j=1;j<=20;j++)            ff[i][j]=ff[ff[i][j-1]][j-1];}int getans(){    for(int i=0;;i++)if(bnum[i]<numblock)        for(int j=i*numblock;;j++)if(!num[j])            return j;}int main(){    scanf("%d%d",&n,&m);    block=pow(n,2.0/3.0)+1+1e-7;    numblock=sqrt(n)+1+1e-7;    for(int i=1;i<=n;i++)        scanf("%d",s+i),last[i]=s[i];    for(int i=1;i<n;i++)    {        int a,b;        scanf("%d%d",&a,&b);        insert(a,b);        insert(b,a);    }    depth[1]=1;    dfs(1,0);    st_chart();         for(int i=1;i<=m;i++)    {        int a,b,d;        scanf("%d%d%d",&d,&a,&b);        if(d==0)        {            c[++tot].pos=a;            c[tot].pre=last[a];            last[a]=b;            c[tot].sub=b;        }        else        {            q[++cnt].l=a;            q[cnt].r=b;            q[cnt].id=cnt;            q[cnt].t=tot;        }    }         sort(q+1,q+cnt+1,cmp);    int l=1,r=1,t=0;         for(int i=1;i<=cnt;i++)    {        while(t>q[i].t)        {            int pos=c[t].pos;            if(inpath[pos])            {                downdate(pos);                s[pos]=c[t].pre;                update(pos);            }            else                s[pos]=c[t].pre;            t--;        }        while(t<q[i].t)        {            t++;            int pos=c[t].pos;            if(inpath[pos])            {                downdate(pos);                s[pos]=c[t].sub;                update(pos);            }            else                s[pos]=c[t].sub;        }        int LCA=lca(q[i].l,q[i].r);        xorpath(q[i].l,l);        xorpath(q[i].r,r);        l=q[i].l;        r=q[i].r;        update(LCA);        ans[q[i].id]=getans();        downdate(LCA);    }    for(int i=1;i<=cnt;i++)        printf("%d\n",ans[i]);    return 0;} 




原创粉丝点击