分块——入门5

这里写图片描述

分析:这个题目超级无敌虚伪,在对整个块开方的时候你会发现你无从下手,须要知道每一个元素,才能知道他们开方后的和,也就是说,难以快速对一个块信息进行更新。

其实你仔细推一推,你会发现,每次开方后向下取整,其实一个数开几次之后你会发现不是0就是1,所以我们只要对整块进行开方后判断一下是不是成为了0或1,在之后的修改中如果已经是0或1可以直接跳过……QWQ
代码:

//By Bibi
///                 .-~~~~~~~~~-._       _.-~~~~~~~~~-.
///             __.'              ~.   .~              `.__
///           .'//                  \./                  \\`.
///        .'//                     |                     \\`.
///       .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
///     .'//.-"                 `-.  |  .-'                 "-.\\`.
///   .'//______.============-..   \ | /   ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int MAXN=5e4+5;
int read()
{
    int sum=0,flag=1;
    char c;
    for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;
    for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';
    return sum*flag;
}
int n,L,op,R,c,num,block,be[MAXN],p[MAXN],a[MAXN],l[MAXN],r[MAXN];
int sum[MAXN];
int f[MAXN];
void build()
{
    num=n/block;
    if(n%block) num++;
    rep(i,1,num)
    {
        l[i]=(i-1)*block+1;
        r[i]=i*block;
    }
    r[num]=n;
}
void ask()
{
    int ans=0;
    if(be[L]==be[R]) rep(i,L,R) ans+=a[i];
    else
    {
        rep(i,L,r[be[L]]) ans+=a[i];
        rep(i,l[be[R]],R) ans+=a[i];
        rep(i,be[L]+1,be[R]-1) ans+=sum[i];
    }
    printf("%d\n",ans);
} 
void add()
{
    if(be[L]==be[R]) rep(i,L,R) sum[be[L]]-=a[i],a[i]=sqrt(a[i]),sum[be[L]]+=a[i];
    else
    {
        rep(i,L,r[be[L]]) sum[be[L]]-=a[i],a[i]=sqrt(a[i]),sum[be[L]]+=a[i];
        rep(i,l[be[R]],R) sum[be[R]]-=a[i],a[i]=sqrt(a[i]),sum[be[R]]+=a[i];
        rep(i,be[L]+1,be[R]-1)
        {
            if(f[i]) continue;
            f[i]=1;sum[i]=0;
            rep(j,l[i],r[i])
            {
                a[j]=sqrt(a[j]),sum[i]+=a[j];
                if (a[j]>1) f[i]=0;
            }
        }
    }
}
void init()
{
    n=read();
    block=sqrt(n);
    rep(i,1,n) a[i]=read(),be[i]=(i-1)/block+1,sum[be[i]]+=a[i];
    build();
    rep(i,1,n)
    {
        op=read();L=read();R=read();c=read();
        if(op) ask();
        else add(); 
    }
}
int main()
{
    init();
    return 0; 
}

猜你喜欢

转载自blog.csdn.net/bbbblzy/article/details/79558488