Codeforces Round 1404 简要题解

A. Balanced Bitstring

B. Tree Tag

C. Fixed Point Removal

先考虑对固定的数组 a a a如何求解。显然如果某个初始的 i < a i i<a_i i<ai一定不可移除,否则我们为了移除它,需要某个时刻在 [ 1 , i − 1 ] [1,i-1] [1,i1]之间移除恰好 i − a i i-a_i iai个。那么我们从左到右扫描,记录当前可移除的最大个数 s u m sum sum,若 i ≥ a i i\geq a_i iai s u m ≥ i − a i sum\geq i-a_i sumiai就意味着可以移除 a i a_i ai,将 s u m sum sum增加 1 1 1。最后构造方案是容易的,只需每次移除可移除的最后一个数即可。
现在还要将一个前缀和后缀变为不可移除。我们考虑对 x x x从大到小扫描,每次将某个 a i a_i ai变为可以移除的话,会引起连锁反应,将后面一些 a i a_i ai变为可以移除。用一个线段树维护当前后缀中还未能移除且 i − a i > 0 i-a_i>0 iai>0的数分别还需要前面移除多少个数,那么每次即为后缀减 1 1 1,查询权值 ≤ 0 \leq 0 0的最小位置。而 y y y的影响仅是一个求前缀和,用树状数组维护当前可以移除的位置集合即可。
时间复杂度为 O ( ( n + q ) log ⁡ n ) \mathcal O((n+q)\log n) O((n+q)logn)

#include <bits/stdc++.h>
#define lowbit(x) (x&-x)
#define inf 0x3f3f3f3f

using namespace std;

typedef long long ll;

namespace BIT {
   

int sumv[300005];

void add(int x,int n) {
   
  for(;x<=n;x+=lowbit(x)) sumv[x]++;
}

int sum(int x) {
   
  int s=0;
  for(;x;x-=lowbit(x)) s+=sumv[x];
  return s;
}

}

namespace SGT {
   

int addv[1200000],minn[1200000];

inline void pushdown(int o) {
   
  if (addv[o]) {
   
  	addv[o*2]+=addv[o];
  	addv[o*2+1]+=addv[o];
  	minn[o*2]-=addv[o];
  	minn[o*2+1]-=addv[o];
  	addv[o]=0;
  }
}

inline void pushup(int o) {
   
  minn[o]=min(minn[o*2],minn[o*2+1]);
}

void init() {
   
  memset(minn,0x3f,sizeof(minn));
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值