zoukankan      html  css  js  c++  java
  • 线段树/学会分析每个数值最多被修改的次数

    You are given an array of N integers. You should support the following queries on this array.

    • 0 L R : Find the minimum integer in the range AL, AL+1, ..., AR.
    • 1 L R X : You should apply the assignment A[i] = A[i] & X, for all indices i in range [L, R], where & denotes bitwise AND operation.

    Input

    First line of the input contains two space separated integers N and Q.

    Second line contains N integer numbers denoting array A.

    In the next Q lines, each contain one of the queries described above.

    Output

    For each query of the type 0, output a single line containing the answer of the query.

    Constraints

    • 1 ≤ N, Q ≤ 105
    • 1 ≤ AiX ≤ 109
    • 1 ≤ L ≤ R ≤ N

    Example

    Input:
    5 5
    1 5 2 3 4
    0 2 5
    1 1 5 6
    0 2 2
    1 2 5 3
    0 1 3
    
    Output:
    2
    4
    0


    题目描述
    给定长度为 N 的整数序列。你需要支持如下操作:
    • 0 L R:查询序列在区间 [L, R] 中的最小值;
    • 1 L R X:对于序列在区间 [L, R] 中的每个元素 Ai,执行操作:Ai ← Ai&X,其中 & 为按 位与操作。

    分析
    区间查询最小值可以用线段树,这道题麻烦的是更新操作,若是对区间里每个数都按位与一遍,必定会超时。这时不要慌,稳定分析,
    &按位与有个特点,即该数的二进制表示为某位为0的话,此后的所以更新,都不会改变该位为0的事实。这样我们可以计算这个区间究竟
    最多能进行多少次&操作?即区间内每个数的每个对应位上1的总数,若某次进行&x操作时,检测一下会不会对区间造成影响,若不会,
    就此打住,这样就避免了许多无用操作,不必每次都更新到叶子结点上。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include <queue>
    #include <vector>
    #include<bitset>
    #include<map>
    #include<deque>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+5;
    const int mod = 77200211+233;
    typedef pair<int,int> pii;
    #define X first
    #define Y second
    #define pb push_back
    //#define mp make_pair
    #define ms(a,b) memset(a,b,sizeof(a))
    const int inf = 0x3f3f3f3f;
    #define lson l,m,2*rt
    #define rson m+1,r,2*rt+1
    
    struct node{
        int a;
        int l,r;
        int st;
        int mid(){
            return (l+r)>>1;
        }
    }tree[maxn<<2];
    
    void pushup(int rt){
        tree[rt].a = min(tree[rt<<1].a,tree[rt<<1|1].a);
        tree[rt].st = tree[rt<<1].st | tree[rt<<1|1].st;
    }
    
    void build(int l,int r,int rt){
        tree[rt].l=l,tree[rt].r=r;
        if(l==r){
            scanf("%d",&tree[rt].a);
            tree[rt].st=tree[rt].a;
            return;
        }
        int m=tree[rt].mid();
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        pushup(rt);
    }
    
    void update(int l,int r,int x,int rt){
        if(l<= tree[rt].l && r>= tree[rt].r){
            int t = tree[rt].st&x;
            if(t==tree[rt].st) return;
        }
        if(tree[rt].l==tree[rt].r){
            tree[rt].a = tree[rt].a & x;
            tree[rt].st=tree[rt].a;
            return;
        }
        int m = tree[rt].mid();
        if(l<=m) update(l,r,x,rt<<1);
        if(r>m) update(l,r,x,rt<<1|1);
    
        pushup(rt);
    }
    
    int query(int l,int r,int rt){
        if(l<= tree[rt].l && r>= tree[rt].r){
            return tree[rt].a;
        }
        int m=tree[rt].mid();
        int ans=inf;
        if(l<=m) ans=min(ans,query(l,r,rt<<1));
        if(r>m) ans=min(ans,query(l,r,rt<<1|1));
        return ans;
    }
    
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            build(1,n,1);
    
            while(m--){
                int x,l,r;
                scanf("%d",&x);
                if(x){
                    int l,r;
                    scanf("%d%d%d",&l,&r,&x);
                    update(l,r,x,1);
                }else{
                    scanf("%d%d",&l,&r);
                    cout<<query(l,r,1)<<endl;
                }
            }
        }
        return 0;
    }
    
    
    
     
  • 相关阅读:
    图像全參考客观评价算法比較
    单片机project师必备的知识
    ACM-并查集之小希的迷宫——hdu1272
    ArcGIS教程:加权总和
    九度 题目1368:二叉树中和为某一值的路径
    解决solr搜索多词匹配度和排序方案
    具体解释linux文件处理的的经常使用命令
    Hotel
    Unity3D 射线指定层获取GameObject 注意 LayerMask
    ios设计一部WindowsPhone手机
  • 原文地址:https://www.cnblogs.com/fht-litost/p/8654722.html
Copyright © 2011-2022 走看看