zoukankan      html  css  js  c++  java
  • 【BZOJ 3133】 3133: [Baltic2013]ballmachine (线段树+倍增)

    3133: [Baltic2013]ballmachine

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 148  Solved: 66

    Description

    有一个装球机器,构造可以看作是一棵树。有下面两种操作:

    • 从根放入一个球,只要下方有空位,球会沿着树滚下。如果同时有多个点可以走,那么会选择编号最小的节点所在路径的方向。比如依次在树根4放2个球,第一个球会落到1,第二个会落到3
    • 从某个位置拿走一个球,那么它上方的球会落下来。比如依次拿走5, 7, 8三个球:

    Input

    第一行:球的个数N,操作个数Q (N, Q <= 100 000)下面N行:第i个节点的父亲。如果是根,则为0 接下来Q行:op num

    1. op == 1:在根放入num个球
    2. op == 2:拿走在位置num的球

    Output

    保证输入合法

    1. op == 1:输出最后一个球落到了哪里
    2. op == 2:输出拿走那个球后有多少个球会掉下来

    Sample Input

    8 4
    0
    1
    2
    2
    3
    3
    4
    6
    1 8
    2 5
    2 7
    2 8

    Sample Output

    1
    3
    2
    2

    HINT

    Source

    【分析】

      没什么人发题解。。

      像我一样看错题的同学看看discuss。。【可怜我只看了样例,然后出的数据对拍的全是祖先的id小于儿子的,就什么也没发现。。

      首先,按照收球顺序弄到dfn,然后每次就是问没有放球的dfn最小的嘛,就用线段树搞这个就好了。【一开始想二分+前缀和logn^2真是很搞笑。。

      第二个拿东西,就是相当于把x往上走最后一个有东西的放到x那里,掉了多少个就用dep求,这个我用倍增搞的。

      就这样啊。不要看错题就好了啊。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<vector>
      7 using namespace std;
      8 #define Maxn 100010
      9 
     10 int mymin(int x,int y) {return x<y?x:y;}
     11 
     12 struct node
     13 {
     14     int x,y,next;
     15 }t[Maxn*2];
     16 int first[Maxn],len;
     17 
     18 void ins(int x,int y)
     19 {
     20     t[++len].x=x;t[len].y=y;
     21     t[len].next=first[x];first[x]=len;
     22 }
     23 
     24 int dfn[Maxn],fn[Maxn],c[Maxn],fa[Maxn],dep[Maxn],mn[Maxn],cnt=0;
     25 int ff[Maxn][20];
     26 bool p[Maxn];
     27 
     28 void dfs1(int x)
     29 {
     30     mn[x]=x;
     31     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
     32     {
     33         int y=t[i].y;
     34         dfs1(y);
     35         mn[x]=mymin(mn[x],mn[y]);
     36     }
     37 }
     38 
     39 bool cmp(int x,int y) {return mn[x]<mn[y];}
     40 
     41 int son[Maxn];
     42 void dfs(int x)
     43 {
     44     dep[x]=dep[fa[x]]+1;
     45     int st=son[0],ed;
     46     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
     47     {
     48         int y=t[i].y;
     49         son[++son[0]]=y;
     50     }ed=son[0];
     51     sort(son+st+1,son+1+ed,cmp);
     52     for(int i=st+1;i<=ed;i++) dfs(son[i]);
     53     dfn[x]=++cnt;
     54     fn[cnt]=x;
     55 }
     56 
     57 
     58 struct nnode
     59 {
     60     int l,r,lc,rc,sm;
     61 }tr[Maxn*2];
     62 
     63 int tot=0;
     64 int build(int l,int r)
     65 {
     66     int x=++tot;
     67     tr[x].l=l;tr[x].r=r;tr[x].sm=0;
     68     if(l!=r)
     69     {
     70         int mid=(l+r)>>1;
     71         tr[x].lc=build(l,mid);
     72         tr[x].rc=build(mid+1,r);
     73     }
     74     else tr[x].lc=tr[x].rc=0;
     75     return x;
     76 }
     77 
     78 void change(int x,int y,int z)
     79 {
     80     if(tr[x].l==tr[x].r)
     81     {
     82         tr[x].sm=z;
     83         return;
     84     }
     85     int mid=(tr[x].l+tr[x].r)>>1;
     86     if(y<=mid) change(tr[x].lc,y,z);
     87     else change(tr[x].rc,y,z);
     88     tr[x].sm=tr[tr[x].lc].sm+tr[tr[x].rc].sm;
     89 }
     90 
     91 int query(int x)
     92 {
     93     if(tr[x].l==tr[x].r) return tr[x].l;
     94     int lc=tr[x].lc,rc=tr[x].rc;
     95     int mid=(tr[x].l+tr[x].r)>>1;
     96     if(tr[lc].sm<mid-tr[x].l+1) return query(tr[x].lc);
     97     return query(tr[x].rc);
     98 }
     99 
    100 int ffind(int x)
    101 {
    102     for(int j=18;j>=0;j--) if(ff[x][j]&&p[ff[x][j]]) 
    103         x=ff[x][j];
    104     return x;
    105 }
    106 
    107 int main()
    108 {
    109     int n,q;
    110     scanf("%d%d",&n,&q);
    111     len=0;
    112     memset(first,0,sizeof(first));
    113     int rt=0;
    114     for(int i=1;i<=n;i++)
    115     {
    116         int x;
    117         scanf("%d",&x);
    118         fa[i]=x;
    119         if(x==0) rt=i;
    120         else ins(x,i);
    121     }
    122     for(int i=1;i<=n;i++) ff[i][0]=fa[i];
    123     for(int i=1;i<=n;i++) p[i]=0;
    124     for(int j=1;(1<<j)<=n;j++)
    125      for(int i=1;i<=n;i++)
    126         ff[i][j]=ff[ff[i][j-1]][j-1];
    127     dep[0]=0;
    128     dfs1(rt);
    129     son[0]=0;dfs(rt);
    130     build(1,n);
    131     for(int i=1;i<=q;i++)
    132     {
    133         int op,x;
    134         scanf("%d%d",&op,&x);
    135         if(op==1)
    136         {
    137             while(x--)
    138             {
    139                 int y=query(1);
    140                 change(1,y,1);
    141                 p[fn[y]]=1;
    142                 if(x==0) printf("%d
    ",fn[y]);
    143             }
    144         }
    145         else
    146         {
    147             if(!p[x]) continue;
    148             int y=ffind(x);
    149             change(1,dfn[y],-1);
    150             p[y]=0;
    151             printf("%d
    ",dep[x]-dep[y]);
    152         }
    153     }
    154     return 0;
    155 }
    View Code

    2017-03-26 20:30:43

  • 相关阅读:
    阿里数据中台
    智慧公安及移动执法平台(中云微迅)
    平安智慧城市的智慧政务
    数据分析师干货-业务逻辑篇
    数据分析师常用商业模型(一)
    智慧政务大数据云平台解决方案
    说几个flink好做spark却不好做的场景
    spark比flink好用的点
    干货好文!自底向上——知识图谱构建技术初探
    用户分析模型
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6623908.html
Copyright © 2011-2022 走看看