• Loj#6284. 数列分块入门 8


    给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c。

    样例输入

    4
    1 2 2 4
    1 3 1
    1 4 4
    1 2 2
    1 4 2

    样例输出

    1
    1
    0
    2
    分析:对于每一个块维护一个覆盖标记. 如果这个块被完整的覆盖了,标记记录的就是对应覆盖的值,否则就是-1.
       查询的时候,对于-1的块,暴力统计,否则看块的覆盖标记是不是c就好了.
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 100010;
    int n,a[maxn],tag[maxn],L[maxn],R[maxn],pos[maxn],block,cnt;
    
    void pushdown(int x)
    {
        if (tag[x] == -1)
            return;
        for (int i = L[x]; i <= R[x]; i++)
            a[i] = tag[x];
        tag[x] = -1;
    }
    
    int solve(int l,int r,int x)
    {
        int res = 0;
        if (pos[l] == pos[r])
        {
            pushdown(pos[l]);
            for (int i = l; i <= r; i++)
            {
                if (a[i] == x)
                    res++;
                a[i] = x;
            }
            return res;
        }
        pushdown(pos[l]);
        for (int i = l; i <= R[pos[l]]; i++)
        {
            if (a[i] == x)
                res++;
            a[i] = x;
        }
        pushdown(pos[r]);
        for (int i = L[pos[r]]; i <= r; i++)
        {
            if (a[i] == x)
                res++;
            a[i] = x;
        }
        for (int i = pos[l] + 1; i <= pos[r] - 1; i++)
        {
            if (tag[i] == -1)
            {
                for (int j = L[i]; j <= R[i]; j++)
                {
                    if (a[j] == x)
                        res++;
                    a[j] = x;
                }
            }
            else
                if (tag[i] == x)
                    res += block;
            tag[i] = x;
        }
        return res;
    }
    
    void print()
    {
        for (int i = 1; i <= n; i++)
            printf("%d ",a[i]);
        printf("
    ");
    }
    
    int main()
    {
        memset(tag,-1,sizeof(tag));
        scanf("%d",&n);
        block = sqrt(n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d",&a[i]);
            pos[i] = (i - 1) / block + 1;
        }
        cnt = (n - 1) / block + 1;
        for (int i = 1; i <= cnt; i++)
        {
            L[i] = R[i - 1] + 1;
            R[i] = min(n,i * block);
        }
        for (int i = 1; i <= n; i++)
        {
            int l,r,c;
            scanf("%d%d%d",&l,&r,&c);
            printf("%d
    ",solve(l,r,c));
        }
    
        return 0;
    }
     
  • 相关阅读:
    函数
    字符编码和文件处理
    内置方法
    day6课后复习
    第四十篇、美颜篇
    第三十八篇、给UITabBar按钮的动画效果
    第三十九篇、NavBar动态隐藏、设置透明、毛玻璃效果
    第九篇、Swift的基本使用
    第三十七篇、毛玻璃效果
    第三十六篇、webService
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8561934.html
Copyright © 2020-2023  润新知