zoukankan      html  css  js  c++  java
  • bzoj3133: [Baltic2013]ballmachine

    我好垃圾a,这个傻逼题都不会

    首先无脑把小球扔下来到达的点的顺序搞出来,这个东西其实不是很好搞。。。我是用一个链表,当前节点为根的子树中,就按孩子子树的最小值为序一个挨一个把每个孩子子树的链表连起来,当前点放最后,然后记录个头记录个尾

    然后相当于在树上建立到序列的映射,扔球就是在序列找前x个变黑,在树上一个点是黑的,它的整个子树都是黑的,于是拿球可以树上倍增找第一个白点,直接改对应位置的颜色,搞个线段树维护一下,倍增logn找颜色logn所以是O(Qlog^2n)的

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    
    #define u first
    #define v second
    #define lc now<<1
    #define rc now<<1|1
    #define mid (ql+qr)/2
    using namespace std;
    typedef pair<int,int> pa;
    const int maxn=110000;
    
    struct node
    {
        int x,y,next;
    }a[maxn];int len,last[maxn];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int mn[maxn],fir[maxn],nxt[maxn],las[maxn];        /**/    int Bin[25],f[25][maxn],dep[maxn];
    priority_queue< pa,vector<pa>,greater<pa> >q;    /**/
    //~~~~~~~~getseq&&倍增~~~~~~~~~~~~~~ 
    void dfs(int x)
    {
        for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]];
        mn[x]=x;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            f[0][y]=x;
            dep[y]=dep[x]+1;
            dfs(y);
            mn[x]=min(mn[x],mn[y]);
        }
        
        for(int k=last[x];k;k=a[k].next)q.push(make_pair(mn[a[k].y],a[k].y));
        while(!q.empty())
        {
            int y=q.top().v;q.pop();
            if(fir[x]==0)fir[x]=fir[y],las[x]=las[y];
            else nxt[las[x]]=fir[y],las[x]=las[y];
        }
        if(fir[x]==0)fir[x]=x,las[x]=x;
        else nxt[las[x]]=x,las[x]=x;
    }
    
    //---------------------------------prepare------------------------------------------------- 
    
    struct trnode{int c,s,p;/*区间颜色,区间白色数量,区间最后一个白的位置*/}tr[maxn*3];
    void pushdown(int now,int ql,int qr)
    {
        if(tr[now].c==0)
        { 
            tr[lc].c=tr[rc].c=0;
            tr[lc].s=mid-ql+1,tr[rc].s=qr-mid;
            tr[lc].p=mid,tr[rc].p=qr;
        }
        else
        {
            tr[lc].c=tr[rc].c=1;
            tr[lc].s=tr[rc].s=0;
            tr[lc].p=tr[rc].p=-1;
        }
    }
    void update(int now)
    {
        if(tr[lc].c==tr[rc].c)tr[now].c=tr[lc].c;
        else tr[now].c=-1;
        tr[now].s=tr[lc].s+tr[rc].s;
        tr[now].p=(tr[rc].p==-1)?tr[lc].p:tr[rc].p;
    }
    void bt(int now,int ql,int qr)
    {
        tr[now].c=0;tr[now].s=qr-ql+1;tr[now].p=qr;
        if(ql<qr)bt(lc,ql,mid),bt(rc,mid+1,qr);
    }
    //~~~~~~~~~in~~~~~~~~~~~~~~~
    
    void change(int now,int ql,int qr,int l,int r,int c)
    {
        if(ql==l&&qr==r)
        {
            tr[now].c=c;
            tr[now].s=(c==0)?qr-ql+1:0;
            tr[now].p=(c==0)?qr:-1;
            return ;
        }
        if(tr[now].c!=-1)pushdown(now,ql,qr);
             if(r<=mid)  change(lc,ql,mid,l,r,c);
        else if(mid+1<=l)change(rc,mid+1,qr,l,r,c);
        else change(lc,ql,mid,l,mid,c),change(rc,mid+1,qr,mid+1,r,c);
        update(now);
    }
    bool ask(int now,int ql,int qr,int p)
    {
        if(tr[now].c!=-1)return tr[now].c;
        if(p<=mid)return ask(lc,ql,mid,p);
        else return ask(rc,mid+1,qr,p);
    }
    int cover(int now,int ql,int qr,int k)
    {
        int ret;
        if(tr[now].s==k){ret=tr[now].p;change(now,ql,qr,ql,qr,k);return ret;}
        if(tr[now].c!=-1)pushdown(now,ql,qr);
        if(k<tr[lc].s)ret=cover(lc,ql,mid,k);
        else if(tr[lc].s==k){ret=tr[lc].p;change(lc,ql,mid,ql,mid,1);}
        else {k-=tr[lc].s;change(lc,ql,mid,ql,mid,1);ret=cover(rc,mid+1,qr,k);}
        update(now);
        return ret;
    }
    //~~~~~~~~~~~out~~~~~~~~~~~~
    
    //------------------------------------segtree---------------------------------------
    
    int sa[maxn],Rank[maxn];
    int main()
    {
        //freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
        int n,Q,x,F;
        scanf("%d%d",&n,&Q); len=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&F);
            if(F==0)x=i; else ins(F,i);
        }
        Bin[0]=1;for(int i=1;i<=24;i++)Bin[i]=Bin[i-1]*2;
        dfs(x);
        for(int i=1,k=fir[x];i<=n;i++,k=nxt[k])
            sa[i]=k,Rank[k]=i;
    
        bt(1,1,n);
        while(Q--)
        {
            scanf("%d",&x);
            if(x==1)
            {
                scanf("%d",&x);
                printf("%d
    ",sa[cover(1,1,n,x)]);
            }
            else
            {
                scanf("%d",&x);
                int i=0,num=0;
                while(i>=0)
                {
                    if(Bin[i]<=dep[x]&&ask(1,1,n,Rank[f[i][x]]))
                        x=f[i][x],num+=Bin[i],i++;
                    else 
                        i--;
                }
                change(1,1,n,Rank[x],Rank[x],0);
                printf("%d
    ",num);
            }
        }
        
        return 0;
    }
  • 相关阅读:
    namespace std 定义的位置
    [Struts]学习日记3 在页面中显示条目列表
    [Hibernate]关于ID的一个容易混淆的地方
    [Struts]"Cannot find bean in any scope"之一解
    [Struts]HibernatePlugIn for Struts(转贴)
    日志搬家了!
    [Struts]学习日记2 增加一些验证
    实验室的项目 讨论
    Struts常见异常信息和解决方法
    参加婚礼
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10312604.html
Copyright © 2011-2022 走看看