zoukankan      html  css  js  c++  java
  • bzoj4631 踩气球

    题意:一共有n个盒子,每个盒子中有ai个气球。共进行q轮操作,在x盒子中踩烂一个气球,并询问有多少的小朋友是高兴的?

    高兴:一共有m个小孩子,每个小孩子的区间为[li,ri],当这个区间盒子中的所有气球都被踩烂他就高兴。

    n<=1e5。

    标程:

     1 #include<cstdio>
     2 #define mid ((l+r)>>1)
     3 using namespace std;
     4 typedef long long ll;
     5 int read()
     6 {
     7     int x=0;char ch=getchar();
     8     while (ch<'0'||ch>'9') ch=getchar();
     9     while ('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar();
    10     return x;
    11 }
    12 const int N=100005;
    13 int seg[N],head[N<<2],cnt,n,m,q,l,r,x,ans;//注意head是线段树上的点连边,大小开4倍! 
    14 ll sum[N<<2];//注意气球总数很多,要开ll! 
    15 struct node{int to,next;}num[N*30];
    16 void add(int x,int y)
    17 {num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
    18 void build(int k,int l,int r)
    19 {
    20     if (l==r) {sum[k]=read();return;}
    21     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    22     sum[k]=sum[k<<1]+sum[k<<1|1];
    23 }
    24 void ins(int k,int l,int r,int L,int R,int x)
    25 {
    26     if (L<=l&&r<=R) {add(k,x);seg[x]++;return;}
    27     if (L<=mid) ins(k<<1,l,mid,L,R,x);
    28     if (R>mid) ins(k<<1|1,mid+1,r,L,R,x);
    29 }
    30 void work(int x)
    31 {
    32    for (int i=head[x];i;i=num[i].next)
    33      if (!--seg[num[i].to]) ans++;
    34 }
    35 void modi(int k,int l,int r,int x)
    36 {
    37     sum[k]--;if (!sum[k]) work(k);
    38     if (l==r) return;
    39     if (x<=mid) modi(k<<1,l,mid,x);
    40       else modi(k<<1|1,mid+1,r,x);
    41 }
    42 int main()
    43 {
    44     n=read();m=read();build(1,1,n);
    45     for (int i=1;i<=m;i++) l=read(),r=read(),ins(1,1,n,l,r,i);
    46     q=read();
    47     while (q--)
    48     {
    49        x=(read()+ans-1)%n+1;
    50        modi(1,1,n,x); printf("%d
    ",ans);
    51     }
    52     return 0;
    53 }

    题解:线段树优化建边

    线段树维护的是气球盒子的区间。

    每个小孩有一段区间,我们将这一段区间拆分成logn个对相应线段树上的区间连边。当这logn个区间的sum都为0时,他高兴。

    对于一个踩气球的操作,相当于是单点修改-1。如果一段区间的sum=0,那么就把依赖它的小孩的seg(仍存在的依赖区间数)-1,如果某小孩的seg=0,那么ans++。

    时间复杂度O((n+q)logn)。

  • 相关阅读:
    matlab中关于使用length导致的不稳定状况。
    matlab 批量读入文件夹中的指定文件类型 (目录级数不限)
    matlab中的图像裁剪,图像抽取,反转,镜像。
    反锐化掩模 unsharp masking【转载】
    matlab 将图像切分为N*N像素的小块
    Python2.7.3 Tkinter Entry(文本框) 说明
    基于JQuery的列表拖动排序
    MAC如何删除开机自启动程序
    MAC配置SVN服务器
    关于MAC清倒废纸篓,项目正在使用
  • 原文地址:https://www.cnblogs.com/Scx117/p/8933743.html
Copyright © 2011-2022 走看看