• Paint The Wall HDU


    题目

    • 区间覆盖[l,r]变成c
    • 区间查询[l,r]里有几个c

    分块求,然后配合map,map好处就是不需要离散化,而且长度可以变话
    有一点就是在求某个数字在分块出现次数时,先进行查找,看这个数字是否出现过。这样可以节省内存,这道题卡内存,要不然直接开一个tag[分块个数][N]
    map[x]操作时,如果map没有x这个数字,它会直接加入x这个数字,但值为0
    初始统计每个分块数字出现的情况,对于某区间修改,中间段采用tag标记,左右两端暴力。每次操作都需要把左右两端的分块进行pushdwon,修改好着一块才能进行暴力

    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int N = 1e5 + 5;
    struct Block{
        int a[N], tag[320];
        int unt;
        std::map<int, int> mp[320];
        void init(int n){
            unt = sqrt(n);
            memset(tag, -1, sizeof(tag));
            for(int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            for(int i = 0; i < 320; i++)
                mp[i].clear();
            for(int i = 1; i <= n; i++)
                mp[(i - 1) / unt + 1][a[i]]++;
        }
        void pushdown(int k){
            if(!~tag[k])return;
            for(int i = (k - 1) * unt + 1; i <= k * unt; i++)
                a[i] = tag[k];
            tag[k] = -1;
        }
        void Modify(int l, int r, int val){
            int le = (l - 1) / unt + 1;
            int re = (r - 1) / unt + 1;
            pushdown(le), pushdown(re);
            if(le == re){
                for(int i = l; i <= r; i++){
                    mp[le][a[i]]--;
                    a[i] = val;
                    mp[le][a[i]]++;
                }
                return;
            }else{
                for(int i = l; i <= le * unt; i++){
                    mp[le][a[i]]--;
                    a[i] = val;
                    mp[le][a[i]]++;
                }
                for(int i = (re - 1) * unt + 1; i <= r; i++){
                    mp[re][a[i]]--;
                    a[i] = val;
                    mp[re][a[i]]++;
                }
                for(int i = le + 1; i <= re - 1; i++){
                    mp[i].clear();
                    mp[i][val] += unt;
                    tag[i] = val;
                }
            }
        }
        int Query(int l, int r, int val){
            int le = (l - 1) / unt + 1;
            int re = (r - 1) / unt + 1;
            int ans = 0;
            pushdown(le), pushdown(re);
            if(le == re){
                for(int i = l; i <= r; i++)
                    ans += a[i] == val;
                return ans;
            }else{
                for(int i = l; i <= le * unt; i++)
                    ans += a[i] == val;
    
                for(int i = le + 1; i <= re - 1; i++)
                    if(mp[i].find(val) != mp[i].end()) ans += mp[i][val];
    
                for(int i = (re - 1) * unt + 1; i <= r; i++)
                    ans += a[i] == val;
            }
            return ans;
        }
    }B;
    
    int main(){
        int n, m;
        while(~scanf("%d%d", &n, &m)){
            B.init(n);
            for(int i = 1; i <= m; i++){
                int op, l, r, val;
                scanf("%d%d%d%d", &op, &l, &r, &val);
                if(op == 1)B.Modify(l + 1, r + 1, val);
                if(op == 2)printf("%d
    ", B.Query(l + 1, r + 1, val));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    FMC子卡设计资料:FMC451基于JESD204B的4路1GspsAD 4路1.25Gsps DA FMC子卡
    Leetcode 416. 分割等和子集 dp
    Leetcode 494. 目标和 dp
    Leetcode 394. 字符串解码
    如何解决linux系统平均负载高(load average)
    Java 对象头那点事
    MICD 分类器
    MED 分类器
    C++学习记录(一)结构体,字符串,内联函数,const,函数参数,函数重载
    C++学习记录(五)this指针,常对象常函数,静态对象静态函数,友元对象友元函数,运算符重载
  • 原文地址:https://www.cnblogs.com/Emcikem/p/12939008.html
Copyright © 2020-2023  润新知