Codeforces 1373 G. Pawns —— 线段树优化

This way

题意:

现在有一张n*n的格子,每次会在x y位置加一个点,如果这个位置有点了就删掉,每个点每次能够往
在这里插入图片描述
走一格,最终到达第x行,并且每个格子只能有一个点。问你每次加入点之后,至少要在n列的基础上加多少列才能让所有点都走到第k行。

题解:

那么这道题目翻译一下就是,给你x y相当于现在有一个横轴,你要在第abs(x-k)+y个位置及之后找一个位置上没没有点并且能够装下它。那么暴力的找肯定是不行的,想了很多解法都是要么时间复杂度太大,要么不满足性质,但是它相当于单点修改,于是可以考虑线段树优化。
那么我们知道,线段树合并是将左右区间的状态转移到当前节点的状态,那么首先我们需要知道的是,
sum:表示这个区间里有多少个点
mx:表示这个区间最右边到哪(不超过这个区间的右端点)
那么光知道了mx还不够,因为会有很多个值在同一个点的情况,于是
ex:表示这个区间右边超过边界的值有几个
那么就可以进行转移了,要考虑很多的情况,其中最重要的就是想到左区间的ex会将右区间的所有空给填满的情况
all表示这个区间最右端到哪,space表示这个区间的未放点的数量有多少

#include<bits/stdc++.h>
using namespace std;
const int N=6e5+5;
int mx[N*4],sum[N*4],ex[N*4];
void push_up(int l,int r,int root){
    sum[root]=sum[root<<1]+sum[root<<1|1];
    int mid=l+r>>1,all=max(0,mx[root<<1|1]-mid+ex[root<<1|1]),space=max(0,all-sum[root<<1|1]);
    ex[root]=max(ex[root<<1|1],ex[root<<1]-(max(all,r-mid)-sum[root<<1|1])+ex[root<<1|1]);
    mx[root]=max(mx[root<<1]+ex[root<<1],mx[root<<1|1]+ex[root<<1|1]);
    mx[root]=max(mx[root],mx[root<<1|1]+ex[root<<1|1]+max(0,ex[root<<1]-space));
    mx[root]=min(mx[root],r);
}
void update(int l,int r,int root,int p,int v){
    if(l==r){
        sum[root]+=v;
        ex[root]=max(0,sum[root]-1);
        mx[root]=sum[root]?r:0;
        return ;
    }
    int mid=l+r>>1;
    if(mid>=p)
        update(l,mid,root<<1,p,v);
    else 
        update(mid+1,r,root<<1|1,p,v);
    push_up(l,r,root);
}
map<int,int>mp[N];
int main()
{
    int n,k,m;
    scanf("%d%d%d",&n,&k,&m);
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        int p=abs(x-k)+y;
        if(mp[x][y]==1)
            update(1,N-1,1,p,-1),mp[x][y]=0;
        else 
            update(1,N-1,1,p,1),mp[x][y]=1;
        printf("%d\n",max(0,mx[1]-n));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值