zoukankan      html  css  js  c++  java
  • 上帝造题的七分钟2 / 花神游历各国(分块)

    好吧,楼下有分块的解法,那么我就再阐述一遍好了

    本以为暴力分块为(TLE)的,结果发现吊打线段树,用奇技淫巧的卡常技术卡到第一页

    评测记录

    其实这道题就是数列分块入门(5)嘛,发现一个数只能被不超过(6)次开方,那么暴力修改,用一个标记看看整块是否有大于(1)的数

    那么我就献上一个未卡常的分块解法

    (Code Below:)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=100000+10;
    ll n,m,a[maxn],sum[330],v[330],pos[maxn],blo;
    
    void change(ll x){
        if(!v[x]){
            v[x]=1;sum[x]=0;
            for(ll i=(x-1)*blo+1;i<=x*blo;i++){
                a[i]=sqrt(a[i]);
                sum[x]+=a[i];
                if(a[i]>1) v[x]=0;
            }
        }
    }
    
    void update(ll l,ll r){
        if(!v[pos[l]]){
            for(ll i=l;i<=min(pos[l]*blo,r);i++){
                sum[pos[i]]-=a[i];
                a[i]=sqrt(a[i]);
                sum[pos[i]]+=a[i];
            }
            v[pos[l]]=1;
            for(ll i=(pos[l]-1)*blo+1;i<=min(pos[l]*blo,n);i++){
                if(a[i]>1){v[pos[l]]=0;break;}
            }
        }
        if(pos[l]!=pos[r]){
            if(!v[pos[r]]){
                for(ll i=(pos[r]-1)*blo+1;i<=r;i++){
                    sum[pos[i]]-=a[i];
                    a[i]=sqrt(a[i]);
                    sum[pos[i]]+=a[i];
                }
                v[pos[r]]=1;
                for(ll i=(pos[r]-1)*blo+1;i<=min(pos[r]*blo,n);i++){
                    if(a[i]>1){v[pos[r]]=0;break;}
                }
            }
        }
        for(ll i=pos[l]+1;i<=pos[r]-1;i++) change(i);
    }
    
    ll query(ll l,ll r){
        ll ans=0;
        for(ll i=l;i<=min(pos[l]*blo,r);i++) ans+=a[i];
        if(pos[l]!=pos[r])
            for(ll i=(pos[r]-1)*blo+1;i<=r;i++) ans+=a[i];
        for(ll i=pos[l]+1;i<=pos[r]-1;i++) ans+=sum[i];
        return ans;
    }
    
    int main()
    {
        scanf("%lld",&n);blo=sqrt(n);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            pos[i]=(i-1)/blo+1;
            sum[pos[i]]+=a[i];
        }
        scanf("%lld",&m);
        ll opt,l,r;
        while(m--){
            scanf("%lld%lld%lld",&opt,&l,&r);
            if(l>r) swap(l,r);
            if(opt==0) update(l,r);
            else printf("%lld
    ",query(l,r));
        }
        return 0;
    }
    
  • 相关阅读:
    正则表达式分组小记
    Python中关于try...finally的一些疑问
    hello,world!
    02操控奴隶——掌握它的语言“Python”
    01操控奴隶——奴隶的构成与运行方式
    vue特殊属性 key ref slot
    vue内置组件 transition 和 keep-alive 使用
    vue文档全局api笔记2
    vue文档全局api笔记1
    vue 二三倍图适配,1像素边框
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/9736440.html
Copyright © 2011-2022 走看看