LOJ 6281 数列分块入门 5

Loj_6281

自己写分块时总是对于一个块内的修改写错

wa了好几次

自我感觉对于块内修改的操作,再封装一个函数是很方便的

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>

using std::min;

const int maxn=50100;

struct node
{
    int l;
    int r;
    int A,B;//A for zero , B for one
    int size,tot;
};

node squ[maxn];
int belong[maxn],size;
long long base[maxn];

void init(int n)
{
    size=floor(sqrt(n));
    for(int i=1,k=1;i<=n;i+=size,k++)
    {
        squ[k].l=i;squ[k].r=min(n,i+size-1);
        squ[k].A=0;squ[k].B=0;squ[k].tot=0;
        squ[k].size=squ[k].r-squ[k].l+1;
        for(int j=squ[k].l;j<=squ[k].r;j++)
        {
            belong[j]=k;
            if(base[j]==0)  ++squ[k].A;
            if(base[j]==1)  ++squ[k].B;
            squ[k].tot+=base[j];
        }
    }
    return ;
}

void modify(int l,int r)
{
    if(squ[belong[l]].A+squ[belong[l]].B==squ[belong[l]].size)  return ;
    for(int i=l;i<=r;i++)
    {
        if(base[i]==1||base[i]==0)  continue;
        squ[belong[i]].tot-=base[i];
        base[i]=floor(sqrt(base[i]));
        squ[belong[i]].tot+=base[i];
        if(base[i]==0)  ++squ[belong[i]].A;
        if(base[i]==1)  ++squ[belong[i]].B;
    }
    return ;
}

void MODIFY(int l,int r)
{
    if(belong[l]==belong[r])    {   modify(l,r);return ;}
    int begin=belong[l],end=belong[r];
    if(squ[belong[l]].l!=l) modify(l,squ[belong[l]].r),++begin;
    if(squ[belong[r]].r!=r) modify(squ[belong[r]].l,r),--end;
    for(int i=begin;i<=end;i++) modify(squ[i].l,squ[i].r);
    return ;
}

int check(int l,int r)
{
    //if(squ[belong[l]].A+squ[belong[l]].B==squ[belong[l]].size)  return squ[belong[l]].B;
    int res=0;
    for(int i=l;i<=r;i++)   res+=base[i];
    return res;
}

int CHECK(int l,int r)
{
    if(belong[l]==belong[r])    return check(l,r);
    int begin=belong[l],end=belong[r],res=0;
    if(squ[belong[l]].l!=l) res+=check(l,squ[belong[l]].r),++begin;
    if(squ[belong[r]].r!=r) res+=check(squ[belong[r]].l,r),--end;
    for(int i=begin;i<=end;i++) res+=squ[i].tot;
    return res;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)   scanf("%d",&base[i]);
    init(n);
    for(int i=1,a,b,c,d;i<=n;i++)
    {
        scanf("%d%d%d%d",&a,&b,&c,&d);
        if(a)
            printf("%d\n",CHECK(b,c));
        else
            MODIFY(b,c);
    }
    return 0;
}

posted @ 2019-01-16 17:21  Lance1ot  阅读(160)  评论(0编辑  收藏  举报