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("\n");
}

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\n",solve(l,r,c));
    }

    return 0;
}

 

 
posted @ 2018-03-13 20:53  zbtrs  阅读(146)  评论(0编辑  收藏  举报