• 回忆旅途的过往


    回忆旅途的过往

    题大意

    n n n 个砝码,每个砝码都有初始重量 a i a_i ai Q Q Q 次操作,每次操作有以下两种

    • 1 , l , r , x 1,l,r,x 1l,r,x:表示把 l l l r r r 的所有 a i a_i ai 变成 x x x
    • 2 , l , r , x 2 , l , r , x 2,l,r,x :查询 [ l , r ] [l, r] [l,r] 的所有砝码,每个砝码可以使用无限次,是否能称出重量 x x x

    a i , x ≤ m a_i , x \le m ai,xm

    保证 a i , x a_i , x ai,x 种数不超过 10 10 10

    n , Q ≤ 1 0 6 , m ≤ 1 0 5 n , Q \le 10^6 , m \le 10^5 n,Q106,m105

    思路

    因为 a i , x a_i , x ai,x 的种数不超过 $10 $ m ≤ 1 0 5 m\le 10^5 m105

    所以考虑 $O(2^{10} * m) $ 把所有情况的答案都预处理出来

    然后用一棵线段树维护区间有什么数。

    用二进制实现

    code

    #include 
    #define fu(x , y , z) for(int x = y ; x <= z ; x ++)
    #define lp p << 1
    #define rp p << 1 | 1
    using namespace std;
    const int N = 1e6 + 5 , M = 1e5 + 5;
    int n , m , Q , vis[N] , tot , cnt , a[N];
    bitset<N> ans[2000];
    struct Tr {     
        int val , lzy;
    } tr[N << 2];
    void pushdown (int p) {
        if (!tr[p].lzy) return;
        tr[lp].lzy = tr[rp].lzy = tr[p].lzy;
        tr[lp].val = tr[rp].val = tr[p].lzy;
        tr[p].lzy = 0;
    } 
    void change (int p , int l , int r , int L , int R , int x) {
        if (L <= l && R >= r)
            tr[p].val = tr[p].lzy = 1 << (x - 1);
        else {
            pushdown (p);
            int mid = l + r >> 1;
            if (L <= mid) change (lp , l , mid , L , R , x);
            if (mid < R) change (rp , mid + 1 , r , L , R , x);
            tr[p].val = tr[lp].val | tr[rp].val;
        }
    }
    int query (int p , int l , int r , int L , int R) {
        if (L <= l && R >= r) 
            return tr[p].val;
        else {
            pushdown (p);
            int mid = l + r >> 1 , ans1 = 0;
            if (L <= mid) ans1 = query (lp , l , mid , L , R);
            if (mid < R) ans1 |= query (rp , mid + 1 , r , L , R);
            return ans1;
        }
    }
    void add (int x) {
        if (vis[x]) return;
        vis[x] = ++tot;
        fu (i , (1 << (tot - 1)) , (1 << tot) - 1) {
            ans[i] = ans[i - (1 << (tot - 1))];
            fu (j , x , m) {
                ans[i][j] = ans[i][j] | ans[i][j - x];
            }
        }
    }
    int main () {
        int t , opt , l , r , x;
        ans[0][0] = 1;
        scanf ("%d%d%d" , &n , &m , &Q);
        fu (i , 1 , n) scanf ("%d" , &a[i]) , add (a[i]);
        fu (i , 1 , n) 
            change (1 , 1 , n , i , i , vis[a[i]]);
        int ans1 = 0;
        while (Q --) {
            scanf ("%d%d%d%d" , &opt , &l , &r , &x);
            if (opt == 1) {
                ans1 ++;
                if (ans1 == 3)
                    ans1 --;
                if (!vis[x]) add (x);
                change (1 , 1 , n , l , r , vis[x]);
            }
            else {
                ans1 ++;
                if (ans1 == 2)
                    ans1 --;
                t = query (1 , 1 , n , l , r);
                puts (ans[t].test (x) ? "Yes" : "No");
            }
        }
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
  • 相关阅读:
    java计算机毕业设计线上文具销售系统源码+数据库+系统+lw文档+mybatis+运行部署
    VBA技术资料MF66:使用代码插入行或列
    element中less,scss,sass穿透设置表格table头的背景色(样式)
    【数据结构】树(七)—— 哈夫曼树(C语言版)
    构建Springboot项目docker容器 时区的设置
    DGL学习笔记——第一章 图
    LuatOS-SOC接口文档(air780E)-- http - http 客户端
    Linux 补丁管理
    linux安装zookeeper
    新手到底应该如何学习Python(python学习路线图)
  • 原文地址:https://blog.csdn.net/fzyyyyyyyy/article/details/133915976