zoukankan      html  css  js  c++  java
  • 【北京集训测试赛(七)/BZOJ4631】踩气球(Balloon)-线段树-STL-Vector

    Problem 踩气球

    题目大意

    给m个区间和一个数列,每次对其中一个数减一,强制在线求每次操作后区间内数字全都为0的区间。

    Solution

    对于数列开一个线段树。对于线段树每一个点开一个vector存区间的id。

    这样我们一共最多会存下$log m$个id。

    对于每次操作,维护线段树sum值。

    当我们将一个数减到了零,那么对于到根路径上的每一个点扫一遍。

    如果这个点的sum值变成零了那么就扫一遍这个点的vector

    判断这个id的区间是否被减完了(额外开一个数组维护就行了)

    如果减成零了那么就ans++。最后我们清空这个vector。

    这样下来,因为每个vector中的东西最多只会访问一遍(然后就删了),

    所以复杂度是$O(q log n+log m)$

    AC Code

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 struct Node{
     7     int l,r,sum;
     8     vector<int> v;
     9 }a[500010];
    10 int lastans=0,bal[100010],ans=0,x,f[100010];
    11 int q,l,r,m,n;
    12 void sg_update(int now){
    13     if(a[now].sum)return;
    14     for(vector<int>::iterator it=a[now].v.begin();it!=a[now].v.end();it++){
    15         bal[*it]-=a[now].r-a[now].l+1;
    16         if(!bal[*it])ans++;
    17     }
    18     a[now].v.clear();
    19 }
    20 void sg_build(int l,int r,int now){
    21     a[now].l=l;a[now].r=r;
    22     if(l==r){
    23         a[now].sum=f[l];
    24         return;
    25     }
    26     int mid=(l+r)>>1;
    27     sg_build(l,mid,now<<1);
    28     sg_build(mid+1,r,now<<1|1);
    29     a[now].sum=a[now<<1].sum+a[now<<1|1].sum;
    30     return;
    31 }
    32 int sg_delete(int now,int x){
    33     if(a[now].l==a[now].r){
    34         a[now].sum--;
    35         sg_update(now);
    36         return ans;
    37     }
    38     int mid=(a[now].l+a[now].r)>>1;
    39     if(x<=mid)sg_delete(now<<1,x);
    40     else sg_delete(now<<1|1,x);
    41     a[now].sum--;
    42     sg_update(now);
    43     return ans;
    44 }
    45 void sg_add(int l,int r,int now,int x){
    46     if(l<=a[now].l&&r>=a[now].r){
    47         a[now].v.push_back(x);
    48         bal[x]=r-l+1;
    49         return;
    50     }
    51     int mid=(a[now].l+a[now].r)>>1;
    52     if(l<=mid)sg_add(l,r,now<<1,x);
    53     if(mid<r)sg_add(l,r,now<<1|1,x);
    54 
    55 }
    56 int main(){
    57 //  freopen("c.in","r",stdin);
    58     scanf("%d%d",&n,&m);
    59     for(int i=1;i<=n;i++)
    60         scanf("%d",&f[i]);
    61     sg_build(1,n,1);
    62     for(int i=1;i<=m;i++)
    63         scanf("%d%d",&l,&r),
    64         sg_add(l,r,1,i);
    65     scanf("%d",&q);
    66     for(int i=1;i<=q;i++)
    67         scanf("%d",&x),
    68         lastans=sg_delete(1,(x+lastans-1)%n+1),
    69         printf("%d
    ",ans);
    70     return 0;
    71 }
  • 相关阅读:
    SP3871 GCDEX
    P2424 约数和
    P6561 [SBCOI2020] 人
    POJ
    约数之和(acwing)
    Codeforces Round #677 (Div. 3)EF
    P1516 青蛙的约会
    VJ的MNNUrank的E
    K. Birdwatching(2019-2020 ICPC Southwestern European Regional Programming Contest (SWERC 2019-20))
    友情提示,本博客仅用于博主自己复习,不适合学习者进行学习
  • 原文地址:https://www.cnblogs.com/skylynf/p/7346504.html
Copyright © 2011-2022 走看看