其他分享
首页 > 其他分享> > Tunnel Warfare(线段树)

Tunnel Warfare(线段树)

作者:互联网

在这里插入图片描述
题目
Sample Input

7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4

Sample Output

1
0
2
4

有三种操作,D是删点,Q是询问点x还和几个点连着,R是恢复最近一次被摧毁的点。对点x,连接着的点的个数显然是右边最近的一个被摧毁的点的坐标减去左边最近的一个点的坐标再减1,即右区间最小值-左区间最大值-1。因为有更新和查询操作,所以可以想到用线段树。
初始化每个点的最大值为0,最小值为n+1,点被删时,最大值最小值等于自己的坐标。

代码

这里要吐槽一下,我先是把mi和mx写反导致样例过不去卡了好久,然后又因为n,m在main函数里又定义了一遍导致一直wa,主要是一直在用一个cpp文件,导致有时候删没删干净,特别是有时候懒得删,以后还是要养成好习惯。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N = 1e6 + 7;
const int M = 1e2+7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;

int n,m;
struct Tree
{
    int mi,mx;
} tree[N];
void build(int node,int l,int r)
{
    if(l==r)
    {
        tree[node].mi=n+1;
        tree[node].mx=0;
        return;
    }
    int mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
    tree[node].mi=min(tree[node<<1].mi,tree[node<<1|1].mi);
    tree[node].mx=max(tree[node<<1].mx,tree[node<<1|1].mx);
}
void update(int node,int pos,int l,int r,int s)
{
    if(l==r)
    {
        if(s==1)
        {
            tree[node].mi=pos;
            tree[node].mx=pos;
        }
        else
        {
            tree[node].mi=n+1;
            tree[node].mx=0;
        }
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        update(node<<1,pos,l,mid,s);
    else
        update(node<<1|1,pos,mid+1,r,s);
    tree[node].mi=min(tree[node<<1].mi,tree[node<<1|1].mi);
    tree[node].mx=max(tree[node<<1].mx,tree[node<<1|1].mx);
}
int query1(int node,int L,int R,int l,int r)
{
    if(L<=l&&r<=R)
    {
        return tree[node].mx;
    }
    int mid=(l+r)>>1;
    if(R<=mid)
        return query1(node<<1,L,R,l,mid);
    else if(L>mid)
        return query1(node<<1|1,L,R,mid+1,r);
    else
        return max(query1(node<<1,L,R,l,mid), query1(node<<1|1,L,R,mid+1,r));
}
int query2(int node,int L,int R,int l,int r)
{
    if(L<=l&&r<=R)
    {
        return tree[node].mi;
    }
    int mid=(l+r)>>1;
    if(R<=mid)
        return query2(node<<1,L,R,l,mid);
    else if(L>mid)
        return query2(node<<1|1,L,R,mid+1,r);
    else
        return min(query2(node<<1,L,R,l,mid), query2(node<<1|1,L,R,mid+1,r));
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int j;
        build(1,1,n);
        stack<int>s;
        rep(i,1,m)
        {
            char c;
            scanf(" %c",&c);
            if(c=='D')
            {
                int x;
                scanf("%d",&x);
                update(1,x,1,n,1);
                s.push(x);
            }
            else if(c=='Q')
            {
                int x;
                scanf("%d",&x);
                int ans;
                int R=query2(1,x,n,1,n);
                int L=query1(1,1,x,1,n);
                if(L==R)
                    ans=0;
                else
                    ans=R-L-1;
                printf("%d\n",ans);
            }
            else
            {
                int j=s.top();
                s.pop();
                update(1,j,1,n,2);
            }
        }
    }
    return 0;
}

标签:node,return,Warfare,Tunnel,mi,线段,tree,int,mx
来源: https://blog.csdn.net/qq_50377393/article/details/119035973