CodeChef-ANDMIN Range Minimum Queries(线段树)

题意:
给出一个序列,两种操作。
0 L R:查询[L,R]中的最小值
1 L R X:[L,R]中的每个数与X进行与操作

思路:
线段树
重点:state变量记录某区间的一种状态,当某节点的state&X==state时,说明不变,这时return,因为下面做的是无用功;否则当该节点只是单纯的一个点,进行与操作,修改state变量。
push_up()操作:或操作
tree[id].state=tree[id2].state|tree[id2+1].state

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#define inf 0x7fffffff

using namespace std;
int n,m,a[100005];

struct node
{
    int l,r,mi,state;
} tree[100005*4];

void push_up(int id)
{
    tree[id].mi=min(tree[id*2].mi,tree[id*2+1].mi);
    tree[id].state=tree[id*2].state|tree[id*2+1].state;
}
void build(int id,int l,int r)
{
    tree[id].l=l;
    tree[id].r=r;
    if(l==r)
    {
        tree[id].mi=tree[id].state=a[l];
        return;
    }
    int mid=l+(r-l)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    push_up(id);
}
void update(int id,int l,int r,int x)
{
    int L=tree[id].l,R=tree[id].r;
    if(l<=L&&R<=r)
    {
        int t=tree[id].state&x;
        if(t==tree[id].state)
            return;
    }
    if(L==R)
    {
        tree[id].mi=tree[id].mi&x;
        tree[id].state=tree[id].mi;
        return;
    }
    if(tree[id*2].r>=l)
    {
        update(id*2,l,r,x);
    }
    if(tree[id*2+1].l<=r)
    {
        update(id*2+1,l,r,x);
    }
    push_up(id);
}
int query(int id,int l,int r)
{
    int L=tree[id].l,R=tree[id].r;
    if(l<=L&&R<=r)
    {
        return tree[id].mi;
    }
    if(l>R||r<L)
        return inf;
    int ans=inf;
    if(tree[id*2].r>=l)
    {
        ans=min(ans,query(id*2,l,r));
    }
    if(tree[id*2+1].l<=r)
    {
        ans=min(ans,query(id*2+1,l,r));
    }
    return ans;
}
int main()
{
    int l,r,z,x;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        build(1,1,n);
        while(m--)
        {
            scanf("%d%d%d",&z,&l,&r);
            if(z==0)
            {
                printf("%d\n",query(1,l,r));
            }
            else
            {
                scanf("%d",&x);
                update(1,l,r,x);
            }
        }
    }
    return 0;
}
发布了19 篇原创文章 · 获赞 0 · 访问量 182

猜你喜欢

转载自blog.csdn.net/qq_43032263/article/details/104420886