码迷,mamicode.com
首页 > 其他好文 > 详细

CF1326E Bombs

时间:2021-02-15 12:22:02      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:class   name   down   缩小   gif   mod   hid   多少   update   

E. Bombs

题意:给定一个排列,和 n 个地雷,按顺序将排列放入集合,遇到地雷则删去集合最大值,求地雷个数为 i 个时,集合最终的最大值为多少。

分析:首先可以看出答案一定是一个非递增序列,考虑类似二分的操作。对于每个节点 i ,若 i 点之后 >= pi 的数量小于等于后面地雷的数量,那 pi 一定会被炸掉,但这样不好维护。依据这点,我们可以尝试枚举答案 x ,每个位置记录 ( >=x的数量 - 地雷的数量) ,当所有的位置的值都 <=0 时,说明答案能取。

题解:按照分析写,区间维护和全局最大值用线段树就行,在缩小答案和增加地雷时,都是前缀的形式+1 -1,因为我们统计的是每个位置之后的数量,那么对于修改时在当前位置之后的结果是没有影响的。

技术图片
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
ll mod=998244353;
ll n,tot,m;
int a[N],c[N],mp[N];
int tr[N<<2],tag[N<<2];
void push_up(int now){
    tr[now]=max(tr[now<<1],tr[now<<1|1]);
}
void push_down(int now,int l,int r){
    int mid=(l+r)/2;
    tag[now<<1]+=tag[now];
    tr[now<<1]+=tag[now];
    tag[now<<1|1]+=tag[now];
    tr[now<<1|1]+=tag[now];
    tag[now]=0;
}
void update(int now,int nl,int nr,int l,int r,int v){
    if(l>=nl&&r<=nr) {tr[now]+=v;tag[now]+=v;return;}
    push_down(now,l,r);
    int mid=(l+r)/2;
    if(mid>=nl) update(now<<1,nl,nr,l,mid,v);
    if(mid+1<=nr) update(now<<1|1,nl,nr,mid,r,v);
    push_up(now);
}
int main() {
//    freopen("../in.in", "r", stdin);
//    ios::sync_with_stdio(false);
    ll k, _;
//    cin>>_;
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),mp[a[i]]=i;
    for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    int ans=n;
    update(1,1,mp[ans],1,n,1);
    for(int i=1;i<n;i++){
        printf("%d ",ans);
        update(1,1,c[i],1,n,-1);
        while(tr[1]<=0){
            ans--;
            update(1,1,mp[ans],1,n,1);
        }
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

CF1326E Bombs

标签:class   name   down   缩小   gif   mod   hid   多少   update   

原文地址:https://www.cnblogs.com/yzccccc/p/14397837.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!