Bombs CodeForces - 1326E 线段树

一开始输出的必定为n,初始时,1~pos[n]都+1,只要tr[1].v>0,那么就说明,不存在位置大于等于pos[k]的炸弹
然后依次进行修改,处理1~q[n],如果tr[1].v<=0,那么就说明,有炸弹的位置大于等于pos[k]
然后k--,再次进行上述操作

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef long long LL;
const int N = 3e5 + 5;
int n;
int p[N], q[N], pos[N];
int maxv[N << 2], lz[N << 2];
struct Node
{
    int l, r;
    LL v;
    LL add;
}tr[N * 4];
//用子节点的信息来计算父节点的信息 
void pushup(int u)
{
    tr[u].v = max(tr[u << 1].v , tr[u << 1 | 1].v);
}
void pushdown(int u)
{
    auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
    if (root.add)
    {
        left.add += root.add;
        left.v += root.add;
        right.add += root.add;
        right.v += root.add;
        root.add = 0;
    }
}
void build(int u, int l, int r)
{
    if (l == r) 
        tr[u] = {l, r, 0, 0};
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}
void modify(int u, int l, int r, int d)
{
    if (tr[u].l >= l && tr[u].r <= r)
    {
        //总和 
        tr[u].v += d;
        //懒标记 
        tr[u].add += d;
    }
    // 区间太大,一定要分裂
    else    
    {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) 
            modify(u << 1, l, r, d);
        if (r > mid) 
            modify(u << 1 | 1, l, r, d);
        //当前区间和发生变化,需要向上传 
        pushup(u);
    }
}
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>p[i],pos[p[i]]=i;
	for(int i=1;i<=n;i++)
		cin>>q[i];
	int k=n;
	//开始一个炸弹都没有
	//直接输出 
	cout<<k<<" ";
	build(1,1,n);
	//0~最大的数所在位置都+1 
	modify(1,1,pos[k],1);
	for(int i=1;i<n;i++)
	{
		//区间修改 
		modify(1,1,q[i],-1);
		while(1)
		{
			//查询区间最大值 
			int maxv=tr[1].v;
			//如果<=0,那么也就说明上面的修改中
			//必有q[i]>=pos[k]
			//也就是说,必定会去除最大值
			//那么当前最大值也就不适用 
			if(maxv<=0)
				//最大值--
				//并把前面的区间都+1
				//如果此时还是<=0
				//说明前面的修改,已经将当前数值去除 
				modify(1,1,pos[--k],1);
			else
				break;
		}
		cout<<k<<" ";
	}
}
int main()
{
	solve();
	return 0;
}
posted @ 2020-03-21 17:11  晴屿  阅读(230)  评论(0编辑  收藏  举报