BZOJ 3133: [Baltic2013]ballmachine

9 篇文章 0 订阅
2 篇文章 0 订阅

让我来装一波逼 WA了之后就被人各种奶70行A不了
然而我就是A了2333 而且第6呢

这道题因为它每次只拿一个点 所以可以一个个拿和一个个放
只需要处理出每个位置为空时下落的顺序 然后用一个优先队列来维护空节点就好了
建一个ST表 取球的时候找到上面第一个有球的点 把它变成空的 下落数目就是dep之差
怎么觉得我现在代码短已经成了一个特色?别人可是打了3k 4k的代码

#include<bits/stdc++.h>
using namespace std;
const int N=100002;
inline int read()
{
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
struct node{int y,next;}a[N];
int g[N],mn[N],f[N][18],dep[N],len,first[N],tot;
void ins(int x,int y){a[++len]=(node){y,first[x]},first[x]=len;}
bool b[N];
bool cmp1(int x,int y){return mn[x]<mn[y];}
struct Cmp
{
    bool operator ()(int &x,int &y){return g[x]>g[y];}
};
priority_queue<int,vector<int>,Cmp>q;
void pre(int x)
{
    mn[x]=x;
    for(int i=1;i<=17;i++)
        if(f[x][i-1])f[x][i]=f[ f[x][i-1] ][i-1];
        else break;
    for(int k=first[x];k;k=a[k].next)
    {
        dep[a[k].y]=dep[x]+1,f[a[k].y][0]=x;
        pre(a[k].y); mn[x]=min(mn[x],mn[a[k].y]);
    }
}
void dfs(int x)
{
    vector<int>p;
    for(int k=first[x];k;k=a[k].next)p.push_back(a[k].y);
    sort(p.begin(),p.end(),cmp1);
    for(int i=0;i<p.size();i++)dfs(p[i]);
    g[x]=++tot;
}
int main()
{
    int i,x,y,n=read(),m=read(),rt;
    for(i=1;i<=n;i++)
    {
        x=read(); f[i][0]=x;
        if(!x)rt=i; else ins(x,i);
    }
    pre(rt); tot=0; 
    dfs(rt);
    for(i=1;i<=n;i++)q.push(i);
    while(m--)
    {
        x=read(),y=read();
        if(x==1){
            while(y--)
                i=q.top(),b[i]=1,q.pop();
            printf("%d\n",i);
        }
        else{
            for(x=y,i=17;~i;i--)if(b[f[y][i]])y=f[y][i];
            b[y]=0; q.push(y);
            printf("%d\n",dep[x]-dep[y]);
        }
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值