排队

来源:互联网 发布:linux 查看局域网ip 编辑:程序博客网 时间:2024/05/01 07:09

题目描述

这里写图片描述

做法

我们先处理出fix表示在全空情况下不断进人,i这个房间被第几个人最终停留。
用一个堆保留空房间当前fix的最小值,每次进一个人就是选择堆中最小值的房间。
拿走人的话观察一下就是从这个房间往上有人房间的数量-1,这个可以倍增来求,因为这个房间到根路径上有人和没人一定是分离开的。
分析一下势能这样做是n log n的。

#include<cstdio>#include<algorithm>#include<set>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+10;int f[maxn][25],fix[maxn],co[maxn],d[maxn],b[maxn*2],sta[100];int h[maxn],go[maxn*2],next[maxn*2];struct dong{    int id,fix;    friend bool operator <(dong a,dong b){        return a.fix<b.fix;    }};set<dong> s;dong zlt;int i,j,k,l,t,n,m,tot,top;int read(){    int x=0;    char ch=getchar();    while (ch<'0'||ch>'9') ch=getchar();    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x;}void add(int x,int y){    go[++tot]=y;    next[tot]=h[x];    h[x]=tot;}void dfs(int x,int y){    f[x][0]=y;    d[x]=d[y]+1;    int i,t=h[x],l=top+1,r=top;    while (t){        if (go[t]!=y) b[++r]=go[t];        t=next[t];    }    sort(b+l,b+r+1);    top=r;    fo(i,l,r) dfs(b[i],x);    top=l-1;    fix[x]=++tot;}int getfather(int x){    int j=floor(log(n)/log(2));    while (j>=0){        if (co[f[x][j]]==1) x=f[x][j];        j--;    }    return x;}void write(int x){    if (!x){        putchar('0');        putchar('\n');        return;    }    top=0;    while (x){        sta[++top]=x%10;        x/=10;    }    while (top){        putchar('0'+sta[top]);        top--;    }    putchar('\n');}int main(){    n=read();m=read();    fo(i,1,n-1){        j=read();k=read();        add(j,k);add(k,j);    }    top=tot=0;    dfs(1,0);    fo(j,1,floor(log(n)/log(2)))        fo(i,1,n)            f[i][j]=f[f[i][j-1]][j-1];    fo(i,1,n){        zlt.id=i;        zlt.fix=fix[i];        s.insert(zlt);    }    while (m--){        t=read();        if (t==1){            k=read();            while (k--){                zlt=*s.begin();                co[zlt.id]=1;                if (!k) write(zlt.id);                s.erase(s.find(zlt));            }        }        else{            k=read();            if (!co[k]){                write(0);                continue;            }            j=getfather(k);            write(d[k]-d[j]);            co[j]=0;            zlt.id=j;            zlt.fix=fix[j];            s.insert(zlt);        }    }}
0 0
原创粉丝点击